.io documentation | General

Accurate Tracking

If your website's design often changes or you have pages with different layouts, use our attributes to get the most accurate data tracking.
With the help of attributes our system will always be able to find necessary data and correctly identify the author/section.
Attributes to use:
If you don't want to indicate the real author's name, you may put ID instead, and use JSON file to send us the list of authors hidden behind the IDs.
Link to JSON file should be sent to your Customer Success Manager or io.support@onthe.io

AJAX

If you have endless scroll please do the following for each content refresh:
  • set new url and page in _io_data_config. For example:
    _io_data_config.url = ‘/canonical-url-of-loaded-article/’;
    _io_data_config.page = ‘Title of loaded article’;
  • add new author and category for each article. In case you do not do this - each article will have the same author and category as the first one had. For example:
    _io_data_config.authors = ‘New author’;
    _io_data_config.categories = ‘New category’;
  • execute the function:
    _io_push_viewed_url(_io_data_config);
Important: each article loaded by AJAX should have html-class io-article-body.

API

Basics

You could get data from API by sending POST-requests to: https://api.onthe.io/{hash}
with such parameters:
{
    "key"      : "{api_key}",
    "entities" : "{list of entities or a single entity}",
    "options"  : "{set-options-here}"
}

Key

Secret key, whis is generated for your project.
Do not share your hash/key pair with others.

Entities

An array of parameters you want to get could contain multiple number of entities to select.
{
    "entities" : {
        "articles" : {
            entity  : "articles",
            details : ["pageviews", "author", "category", "timeread", "social", "sources"]
        },
        "categories"  : {
            entity  : "categories",
            details : ["title"]
        }
    }
}

Options

The array of parameters, which will be added for each entity-element from entities array can consist of such elements:
  • period - the timeframe to extract the data
  • Examples:
        
    "period": {name: "realtime"} 
    "period": {name: "now"} 
    "period": {name: "hour"} 
    "period": {name: "today"} 
    "period": {name: "week"} 
    "period": {name: "month"} 
    
    Set timeframe "2017-05-20" to "2017-05-25"
    {
        "period": {
            name: "range",
            at_from: "2017-05-20",
            at_to: "2017-05-25"
        } 
    }
        
    Set timeframe "2017-07-01"
    {
        "period": {
            name: "today",
            at: "2017-07-01"
        }
    }
    
  • per_page - number of elements on one page
  • offset - page number (starts from 0)
  • order - parameter to sort (e.g. pageviews, fb, readability, recirculation)
  • direction - sequence (ASC or DESC)

Examples:

TOP-20 articles for today

{
    "key" : "{api_key}",
    "entities" : {
        "articles" : {
            entity : "articles",
            details : ["pageviews", "author", "category", "timeread", "social", "sources"]
        }
    },
    "options" : {
        "period" : {
            name : "today"
        },
        per_page : 20
    }
}

Categories data for a week

{
    "key" : "{api_key}",
    "entities" : {
        "categories" : {
            entity : "categories",
            details : ["title", "pageviews"]
        }
    },
    "options" : {
        "period" : {
            name : "week"
        }
    }
}

TOP-10 authors for today

{
    "key" : "{api_key}",
    "entities" : {
        "authors" : {
            entity : "authors",
            details : ["pageviews", "readability", "count_pub"]
        }
    },
    "options" : {
        "period" : {
            name : "today"
        },
        per_page : 10
    }
}

List of articles filtered by author

{
    "key" : "{api_key}",
    "entities" : {
        "articles" : {
            entity : "articles",
            details : ["pageviews", "author", "category", "timeread", "social", "sources"],
            filters : {
                author: {author_id-value-from-"authors"-entity}
            }
        }
    },
    "options" : {
        "period" : {
            name : "today"
        },
        per_page : 20
    }
}

List of articles filtered by category

{
    "key" : "{api_key}",
    "entities" : {
        "articles" : {
            entity : "articles",
            details : ["pageviews", "author", "category", "timeread", "social", "sources"],
            filters : {
                category: {category_id-value-from-"categories"-entity}
            }
        }
    },
    "options" : {
        "period" : {
            name : "today"
        },
        per_page : 20
    }
}

List of articles filtered by search traffic

{
    "key" : "{api_key}",
    "entities" : {
        "articles" : {
            entity : "articles",
            details : ["pageviews", "author", "category", "timeread", "social", "sources"]
        }
    },
    "options" : {
        "period" : {
            name : "today"
        },
        "filters" : {
            source_group: "search"
        }
        per_page : 20
    }
}

Detailed data about the article

{
    "key" : "{api_key}",
    "entities" : {
        "articles" : {
            entity : "articles",
            details : ["pageviews", "author", "category", "timeread", "social", "sources", "readability", "recirculation", "next_pages", "date_pub", "chart", "domain", "funnel"],
            filters : {
                url: "/path/of/url/on/your/site"
            }
        }
    },
    "options" : {
        "period" : {
            name : "today"
        }
    }
}

Example in JS:

TOP-10 authors for today

var io={ajax:function(e,n,t,r){var o=new XMLHttpRequest;o.open(r||"POST",e,!0),o.onreadystatechange=function(){4==o.readyState&&200!=o.status&&t&&t(null),4==o.readyState&&200==o.status&&t&&t(o.responseText?JSON.parse(o.responseText):null)},o.setRequestHeader("Content-type","application/x-www-form-urlencoded"),o.send(n?io.query(n):null)},urlencode:function(e){return e=(e+"").toString(),encodeURIComponent(e).replace(/!/g,"%21").replace(/'/g,"%27").replace(/\(/g,"%28").replace(/\)/g,"%29").replace(/\*/g,"%2A").replace(/%20/g,"+")},query:function(e,n,t){var r,o,u=[],a=this,c=function(e,n,t){var r,o=[];if(!0===n?n="1":!1===n&&(n="0"),null!==n&&"object"==typeof n){for(r in n)null!==n[r]&&o.push(c(e+"["+r+"]",n[r],t));return o.join(t)}return"function"!=typeof n?a.urlencode(e)+"="+a.urlencode(n):"function"==typeof n?"":void 0};t||(t="&");for(o in e)r=e[o],n&&!isNaN(o)&&(o=String(n)+o),u.push(c(o,r,t));return u.join(t)}};

var params = {
    "key" : "{api_key}",
    "entities" : {
        "authors" : {
            entity : "authors",
            details : ["pageviews", "readability", "count_pub"]
        }
    },
    "options" : {
        "period" : {
            name : "today"
        },
        per_page : 10
    }
};

io.ajax('https://api.onthe.io/{hash}', params, function (r) {
    
});

Example in PHP:

TOP-10 authors for today

<?php

$params = [
    'key' => "{api_key}",
    'entities' => [
        'authors' => [
            'entity' => 'authors',
            'details' => ['pageviews', 'readability', 'count_pub']
        ]
    ],
    'options' => [
        'period' => [
            'name' => 'today'
        ],
        'per_page' => 10
    ]
];


$url = 'https://api.onthe.io/{hash}';

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
curl_close($ch);

print_r(json_decode($response, true));

Application tracking

Sending data is as simple as sending simple HTTPS GET requests.
Exmaple of regular request:
https://tt.onthe.io/?k[]={app_id}:pageviews[page:Some article title,category:SPORT, ...]&s=a63fa7bd0cb420398c55518ee76b0a3f.
Param pageviews we call a metric, and page and category are slices.
Slices values sent to the t system should not contain commas ( , ) or colons ( : ). Commas and colons should be replaced by #44; and #58; accordingly. All values in slices should be URL-encoded and have UTF-8 encoding.

Slices *Required slices

Slice Description Example
page* Article title Breaking news#58; Project General has been connected to io analytics system
category Article category (or section) SPORT
author Article author. If page is article or news, slice author is required John Doe
previous_page Previous page title, from which the user came. If there is no such a page - this slice should be omitted; If user came from the main page - the value of this slice will be Main Page Breaking news#58; Project General wants to be connected to io analytics system
platform Platform of the app iOS
referrer Referrer It's required to set referrer value to app for application
domain Domain {hostname}
url Article pathname /some/article/url

Pageviews

pageviews metric should be sent when the user opens an article.

Read finished

read_finished metric should be sent if user read the article to the end.

Uniques

uniques metric should be sent only if user opened the app for the first time during 24 hours.

Visits

visits metric should be sent not earlier than 15 minutes after the end of the user session.

Time

Metric time This metric should be sent every 10 seconds after the user opened an article. This metric shows how much time did the user spend on a page. This metric should contain only one slice - page.

Articles Tracking

To send us data about the article please do the following:
  • Add the javascript-code to all the Article pages:
  • Add this class to the text block: io-article-body. For example:
    Article text
    or add class io-article-body to existen class of an article:
    Article text
Important: By default we track the article by URL in the address line. If one article can be available by more than 1 URL, please do the following:
  • if you have a canonical URL of the article in meta tags (), then add to _io_data_config a field useCanonical with true value. For example:
  • otherwise add to _io_data_config a url field with a value of canonical URL of the article. For example:
This is necessary to track one article as one item in the dashboard.

Articles’ titles

By default we track the title of the article from tag of the website page. If you want to track some other title please set it statically or dynamically in a following way:
_io_data_config.page = ‘Article title’;
or
_io_data_config.page = variable.from.your.cms;

Authors and Categories (Sections)

You can set author and section statically or dynamically in a following way:
_io_data_config.authors = ‘Author name’;
_io_data_config.categories = ‘Category name’;
or
_io_data_config.authors = cms.variable.author;
_io_data_config.authors = document.querySelector(‘.author-class’).textContent;
_io_data_config.categories = cms.variable.category;
_io_data_config.authors = document.querySelector(‘.category-class’).textContent;
If one article belongs to a few authors and/or categories, please put commas between them:
_io_data_config.authors = ‘Author1,Author2,Author3’;
_io_data_config.categories = ‘Category1,Category2,Category3’;
If you don't want to indicate the real author's name, you may put ID instead, and use JSON file to send us the list of authors hidden behind the IDs.
Link to JSON file should be sent to your Customer Success Manager or io.support@onthe.io

Mobile version of the site

To track mobile version please add the same config as you did for the desktop.
Important: URL has to be the same in _io_data_config on mobile and desktop.

Authors ID

If you don't want to show your authors or categories on a page but you have an id of the authors and you want to track these data you need to include this HTML-code:
And you need to contact with your .io manager and give him an url to authors list.
Example of list in JSON:

News blocks

.io can track data from some page blocks and also show CTR of this block and share of viewers. To do this you must take a few steps:

Step 1.

Put attribute data-vr-zone with a name of block you want to track.

Step 2.

Put attribute data-vr-contentbox with a position name of this link in block.

Step 3.

Enjoy ;)

Example:



Classic tracking

You need to include this JS-code into a page to track pageview data from your website:

Following from FB Group

If you want to track links from your facebook group you need to include label ?f in post's link

Google AMP

If you want to track data from Google AMP pages you need to insert code below to your website:

Into tag <head>:



Into tag <body>:

    

Hidden authors / categories

If you don't want to show your authors or categories on a page but you want to track these data you need to include this HTML-code:
The same thing with categories:

Facebook Instant Articles

If you want to track data from Facebook Instant Articles pages you need to insert code below to your Instant Articles page in <body> block without any additional elements in the header or footer blocks:

Documentation

Basic tracking:

Our javascript-code:
Insert it before the tag to all the website pages. Thus you will ensure that all the pageviews are sent to our system. Articles data To send us data about the article please do the following: 1) Add the javascript-code to all the Article pages: 2) Add this class to the text block: io-article-body. For example:
Article text
or add class io-article-body to existen class of an article:
Article text
Important: By default we track the article by URL in the address line. If one article can be available by more than 1 URL, please do the following: - if you have a canonical URL of the article in meta tags (), then add to _io_data_config a field useCanonical with true value. For example: - otherwise add to _io_data_config a url field with a value of canonical URL of the article. For example: This is necessary to track one article as one item in the dashboard. Articles’ titles By default we track the title of the article from tag of the website page. If you want to track some other title please set it statically or dynamically in a following way: _io_data_config.page = ‘Article title’; or _io_data_config.page = variable.from.your.cms; Authors and Categories (Sections) You can set author and section statically or dynamically in a following way: _io_data_config.authors = ‘Author name’; _io_data_config.categories = ‘Category name’; or _io_data_config.authors = cms.variable.author; _io_data_config.authors = document.querySelector(‘.author-class’).textContent; _io_data_config.categories = cms.variable.category; _io_data_config.authors = document.querySelector(‘.category-class’).textContent; If one article belongs to a few authors and/or categories, please put commas between them: _io_data_config.authors = ‘Author1,Author2,Author3’; _io_data_config.categories = ‘Category1,Category2,Category3’; Mobile version of the site To track mobile version please add the same config as you did for the desktop. Important: URL has to be the same in _io_data_config on mobile and desktop. Endless scroll and AJAX If you have endless scroll please do the following for each content refresh: set new url and page in _io_data_config. For example: _io_data_config.url = ‘/canonical-url-of-loaded-article/’; _io_data_config.page = ‘Title of loaded article’; add new author and category for each article. In case you do not do this - each article will have the same author and category as the first one had. For example: _io_data_config.authors = ‘New author’; _io_data_config.categories = ‘New category’; execute the function: _io_push_viewed_url(_io_data_config); Important: Each article loaded by AJAX should have html-class io-article-body. Number of articles To track the number of published articles (including the number for each author and/or category) please create a RSS 2.0, Atom or JSON feed, where all the new articles will be added. The most appropriate number of articles in the feed is 30. Data formats: RSS 2.0: (about: https://wikipedia.org/wiki/RSS) Channel object consists of the following items: { "title": "article title", "link": "canonical URL of the article", "pubDate": "date when the article was published in UTC format", "author": "article author", (if there are a few - split them with a comma) "category": "article category" (if there are a few - split them with a comma) } ATOM: (about: https://wikipedia.org/wiki/Atom) Content object consists of the following entries: { "title": "article title", "link[href]": "canonical URL of the article", //link with a href attribute (check atom standard) "updated": "date when the article was published in GMT or UTC format", "author": "article author", (if there are a few - split them with a comma) "category": "article category" (if there are a few - split them with a comma) } JSON: (about: https://wikipedia.org/wiki/JSON) Elements array with the following parameters: { "title": "article title", "link": "canonical URL of the article", "pubDate": "date when the article was published in UTC format", "author": "article author", (if there are a few - split them with a comma) "category": "article category" (if there are a few - split them with a comma) } You can check your RSS 2.0 and Atom feeds with this link: https://validator.w3.org/

Tracking Setup

You need to include this JS-code into a page to track pageview data from your website:

User type

If you want to track some users type (authorized, guest etc.), you need to include HTML-code into every page on a website:

Youtube tracking

To be able to track Youtube embedded videos on a website we use Youtube's API. It requires to use additional parameters in 'src' attribute of iframe when embedding video to the page. Those parameters are `enablejsapi` and `origin`.
`enablejsapi` pararameter must be allways set to 1. `origin` parameter must match your site's origin.
For example, we are trying to embed video bellow to our article
To do this we are using code like this :
 
To give IO's code availability to track this video we need to change this:
src="https://www.youtube.com/embed/9nZMHBDw8os"
To this:
 src="https://www.youtube.com/embed/9nZMHBDw8os?enablejsapi=1&origin={link_project}" 
So we got code of embedded element like this:
 
If you don't want to modify all video content on your website we can do it dynamically. Our code can modify your Youtube iframe's src before it loads so this procedure will look absolutelly seamless to your website's visitors