Skip to content

Developer documentation

One line of code, and the reports fill up

Add the script, register the events you care about, and read everything else here: single-page apps, Content Security Policy, the collection API and what each response means.

Quickstart

Add your domain on the InfoPeak Analytics page in your account. You get a site key right away: 32 random hexadecimal characters. Paste the line below just before the closing </body> tag on every page you want to measure.

<script defer src="https://analytics.infopeak.io/ipk.js" data-site="YOUR_SITE_KEY"></script>

That is the whole installation. The first visit shows up on the site page within seconds.

The site key is public by design; it is visible in your page source. What protects it is domain binding: calls from a domain that is not registered for the site are rejected. See Domain binding.

How it works

The script stores nothing on the visitor's device: no cookies, no localStorage, no sessionStorage, no fingerprinting. The server derives a visitor identifier from the IP address, the user agent, the site and the date together with a secret, so it changes at midnight UTC and is different on every site. The IP address and the user agent are not stored.

Page views less than 30 minutes apart form one visit. A new campaign (a different utm_source or utm_campaign) starts a new visit. If the browser sends a Do Not Track signal, the script sends nothing at all. Self-declared bots, crawlers and headless browsers are ignored.

Script attributes

  • data-site Required. Your site key.
  • data-auto="off" Turns off the automatic events (outbound clicks, downloads, scrolling) and automatic page views on route changes. Time on page is still measured.
  • data-search Sends site search terms. Also turn on Measure site search in the site settings; the server rejects search terms for sites where it is off.
<script defer src="https://analytics.infopeak.io/ipk.js" data-site="YOUR_SITE_KEY" data-search></script>

The line on the site page always reflects your settings, so copying it from there gives you the right attributes.

Page views and single-page apps

A page view is sent when the script loads. Prerendered pages are counted when someone actually looks at them. In single-page apps, history.pushState, replaceState and the back button send a page view whenever the path changes, with the previous address as referrer. You do not need to do anything.

If your router changes pages some other way, send the page view yourself. A manual call for the same path within one second of an automatic one is ignored, so calling it as well does no harm.

ipk('pageview');

To call ipk() before the script has loaded, add this stub first. Calls are queued and replayed.

<script>window.ipk = window.ipk || function () { (window.ipk.q = window.ipk.q || []).push(arguments); };</script>

Only the path is sent, never the query string. Campaign tags are read separately, see Campaigns.

Custom events

Register the event name under Your own events in the site settings first. Names that are not registered are rejected, which keeps a typo or an event per article from filling your reports with thousands of names.

ipk('event', 'ticket_purchased', { exhibition: 'klimt', tickets: 2 });
  • name Lowercase letters, digits, _ and -, 1 to 48 characters. Up to 50 registered names per site.
  • properties Optional object, at most 4 KB as JSON. Larger properties are dropped and the event is stored without them.
Do not put personal data in event names, properties or page paths: no names, email addresses or customer numbers. Paths and properties are stored as they are sent. Mark the events that matter as key events with the star in the events table.

Automatic events

These are measured without registration unless the script has data-auto="off". Their properties are fixed; anything else is removed on the server.

  • outbound_click A click on a link to another host name. Property host.
  • file_download A click on a link to a file ending in pdf, doc(x), xls(x), ppt(x), odt, ods, odp, rtf, txt, csv, zip, rar, 7z, gz, dmg, exe, msi, pkg, apk, epub, mp3, wav, mp4, mov, avi, wmv or mkv. Properties file and ext.
  • scroll Scrolling to 90 % of a page, once per page view. Property percent.
  • site_search Only with data-search and the site setting on. Reads q, s, search, query or keyword from the address. Property term, at most 100 characters.

Time in view and scroll depth are reported when the page is hidden or left, before a link click that leaves the page, and before a route change.

Campaigns

utm_source, utm_medium, utm_campaign, utm_content and utm_term are read from the address and stored in lowercase. Together with the referring site they decide the channel, using the standard grouping: direct, organic search, paid search, organic social, paid social, organic video, paid video, email, referral, display, affiliates, other paid and unassigned.

https://example.com/exhibitions?utm_source=newsletter&utm_medium=email&utm_campaign=autumn

Domain binding

Calls are accepted from the site's domain and all its subdomains: a site on example.com accepts www.example.com and shop.example.com, but not badexample.com. Add up to 20 extra domains in the site settings.

The check uses the browser's Origin header, or Referer when Origin is missing. localhost and bare IP addresses are not accepted, so test on a staging subdomain of your domain.

Domain binding stops a copied site key from being used in another browser page. It cannot stop a server that forges its own Origin header, and no browser-side analytics can.

Content Security Policy

If your site sends a Content Security Policy, allow the script and the collection endpoint:

script-src  'self' https://analytics.infopeak.io;
connect-src 'self' https://analytics.infopeak.io;

The script sends its data as text/plain with navigator.sendBeacon, so there is no preflight request.

Collection API

The script is the supported way to send data. If you need to send from your own code in the browser, post the same JSON:

POST https://analytics.infopeak.io/collect.php, body as JSON with content type text/plain, at most 8 KB.

  • k Site key.
  • t pageview, event or engagement.
  • p Page path.
  • r Referring address, or null.
  • i Page view id, 16 hexadecimal characters. Ties engagement to its page view.
  • u Campaign object: source, medium, campaign, content, term.
  • w Screen width in pixels. Stored only as a range.
  • l Browser language, for example de-AT. Stored only as de.
  • e Event name (event only).
  • m Event properties (event only).
  • ms Milliseconds in view (engagement only).
  • sc Scroll depth in percent (engagement only).
fetch('https://analytics.infopeak.io/collect.php', {
  method: 'POST',
  headers: { 'Content-Type': 'text/plain;charset=UTF-8' },
  body: JSON.stringify({ k: 'YOUR_SITE_KEY', t: 'event', p: location.pathname, e: 'ticket_purchased', m: { tickets: 2 } }),
  keepalive: true
});

Quotas

Each site has a monthly limit of page views. The month is a calendar month in UTC.

  • Free 10,000 page views a month
  • Pro 500,000 page views a month
  • Business 5,000,000 page views a month
  • Enterprise Agreed volume

Above the limit, page views and events are rejected with 429 until the next month or until the site moves to a larger plan. Engagement reports do not count towards the limit. See pricing.

Errors

A stored call answers 204 with no body. Errors answer JSON with an error code.

  • 400 bad_body The body is empty or larger than 8 KB.
  • 400 bad_json The body is not a JSON object.
  • 400 bad_path The page path could not be read.
  • 400 unknown_event The event name is not registered, or it is an automatic event that is turned off for the site.
  • 403 domain_not_allowed The calling page is not on a domain registered for the site.
  • 404 unknown_site_key No active site has this key.
  • 405 method_not_allowed Only POST (and the preflight OPTIONS) is accepted.
  • 429 quota_exceeded The site has used its monthly limit.
  • 503 unavailable A temporary problem on our side. The script never retries and never slows your page.

Rejected calls are counted, and the site page shows a notice when there are any, so a wrong domain does not just look like no visitors.

Ready to measure?

Create a free site and see your first visit in a few minutes.

Create a free site