Liberate your daily statistics from JetPack


Because Ma.tt continues to burn all of the goodwill built up by WordPress, and JetPack have decided to charge a ridiculous sum for their statistics, I've decided to move to a new stats provider. But I don't want to lose all the statistics I've built up over the years.

How do I download a day-by-day export of my JetPack stats0?

Luckily, there is an API for downloading all your JetPack stats!

First, get your API key by visiting https://apikey.wordpress.com/ - it should be a 12 character string. For this example, I'm going to use 123456789012. You will need to use your own API key.

There is some brief documentation on that page. Here are the bits we are interested in:

api_key     String    A secret unique to your WordPress.com user account.
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.
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.
limit       Integer   The maximum number of records to return. Default is 100. "-1" means unlimited. If days is -1, limit is capped at 500.
format      String    The format the data is returned in, 'csv', 'xml' or 'json'. Default is 'csv'.

In order to get all of the statistics from a single day, the URl is:

https://stats.wordpress.com/csv.php?api_key=123456789012
     &blog_uri=https://shkspr.mobi/blog/
     &table=postviews
     &end=2024-10-07
     &days=1
     &limit=-1

That gets all of the statistics from one specific day. The limit=-1 means it will retrieve all the records of that day1.

That will get you a CSV which looks like:

CSV CSV"date","post_id","post_title","post_permalink","views"
"2024-10-09",0,"Home page","https://shkspr.mobi/blog/",59
"2024-10-09",42171,"Review: HP's smallest laser printer - M140w + Linux set up","https://shkspr.mobi/blog/2022/04/review-hps-smallest-laser-printer-m140w-linux-set-up/",7
"2024-10-09",49269,"No, Oscar Wilde did not say ""Imitation is the sincerest form of flattery that mediocrity can pay to greatness""","https://shkspr.mobi/blog/2024/01/no-oscar-wilde-did-not-say-imitation-is-the-sincerest-form-of-flattery-that-mediocrity-can-pay-to-greatness/",7
"2024-10-09",53333,"The Cleaner 🆚 Der Tatortreiniger - Series 3","https://shkspr.mobi/blog/2024/10/the-cleaner-%f0%9f%86%9a-der-tatortreiniger-series-3/",7
"2024-10-09",49943,"Solved! ""Access Point Name settings are not available for this user""","https://shkspr.mobi/blog/2024/03/solved-access-point-name-settings-are-not-available-for-this-user/",7
"2024-10-09",43690,"WhatsApp Web for Android - a reasonable compromise?","https://shkspr.mobi/blog/2022/11/whatsapp-web-for-android-a-reasonable-compromise/",5

You can also get a JSON file using &format=json, although it doesn't contain the permalinks.

JSON JSON[
    {
        "date": "2024-10-09",
        "postviews": [
            {
                "post_id": 0,
                "post_title": "",
                "permalink": "",
                "views": 59
            },
            {
                "post_id": 49269,
                "post_title": "No, Oscar Wilde did not say \"Imitation is the sincerest form of flattery that mediocrity can pay to greatness\"",
                "permalink": "",
                "views": 9
            },
            {
                "post_id": 42171,
                "post_title": "Review: HP's smallest laser printer - M140w + Linux set up",
                "permalink": "",
                "views": 7
            },

From there, I wrote a scrap of Python to download every single date individually.

Python 3 Python 3import requests
import datetime
import os
import json

# Directory to save the JSON files
save_dir = "jetpack_stats"
os.makedirs(save_dir, exist_ok=True)

# URL of the API
base_url = "https://stats.wordpress.com/csv.php?api_key=123456789012"+\
           "&blog_uri=https://example.com/"+\
           "&table=postviews"+\
           "&days=1"+\
           "&format=json"+\
           "&limit=-1"+\
           "&end="

# Make API call and save the response
def fetch_and_save_json(date):
    # Format the date as ISO8601 (YYYY-MM-DD)
    formatted_date = date.isoformat()

    # Make the API call
    url = f"{base_url}{formatted_date}"
    response = requests.get(url)

    if response.status_code == 200:
        data = response.json()
        file_name = f"{formatted_date}.json"
        file_path = os.path.join(save_dir, file_name)
        with open(file_path, "w") as f:
            json.dump(data, f, indent=4)

        print(f"Saved {formatted_date}")
    else:
        print(f"Failed! {formatted_date} status code: {response.status_code}")

# Iterate over a date range
start_date = datetime.date(2023,  1 , 1)
end_date   = datetime.date(2024, 10, 30)

# Loop through all dates
current_date = start_date
while current_date <= end_date:
    fetch_and_save_json(current_date)
    current_date += datetime.timedelta(days=1)

You'll need to manually find the earliest date for which your blog has statistics.

Running the code is a little slow. Expect about 3 minutes per year of data. I'm sure you could parallelise it if you really needed to.

Now, for my next trick, how do I import these data into a new stats plugin? That's tomorrow's blog post!


  1. When people ask on the official support forum, they're told to privately contact JetPack. There's a help page which shows how to download a summary. But I couldn't find anything more fine-grained than that. ↩︎

  2. The maximum number of records for a specific day in my dataset was 978. ↩︎


Share this post on…

  • Mastodon
  • Facebook
  • LinkedIn
  • BlueSky
  • Threads
  • Reddit
  • HackerNews
  • Lobsters
  • WhatsApp
  • Telegram

2 thoughts on “Liberate your daily statistics from JetPack”

Trackbacks and Pingbacks

What links here from around this blog?

What are your reckons?

All comments are moderated and may not be published immediately. Your email address will not be published.

Allowed HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <p> <pre> <br> <img src="" alt="" title="" srcset="">