UsherStats Docs Contents usherstats.com Start free

Analytics

Every figure in the dashboard comes from one query catalogue, and the API exposes it as it is: you name a metric set, a dimension and a few numbers, and UsherStats writes the query. There is no SQL to send and nothing to escape. The dashboard reads through these same routes.

All of them need the analytics:read scope. A site in another workspace, or outside a token's site restriction, is 404.

RouteScope
GET /v1/stats/catalogueanalytics:read
GET /v1/sites/{id}/statsanalytics:read
POST /v1/sites/{id}/stats/queryanalytics:read
POST /v1/sites/{id}/stats/batchanalytics:read
GET /v1/sites/{id}/summaryanalytics:read
GET /v1/sites/{id}/top/{dimension}analytics:read
POST /v1/sites/{id}/internal-linksites:write

The examples assume $US_TOKEN holds a token with account:admin. First, a site to read:

curl https://api.usherstats.com/v1/sites \
  -H "Authorization: Bearer $US_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "Field notes", "hostnames": ["fieldnotes.example"]}'

The catalogue

Four metric sets: pageviews (confirmed pageviews in a browser), sessions, requests (everything your server or proxy answered, crawlers included) and events. Each lists its lanes (human, bot, internal), the dimensions it can be broken down by, the filters it takes and the counts it can sort by.

curl https://api.usherstats.com/v1/stats/catalogue \
  -H "Authorization: Bearer $US_TOKEN"

One query

A spec is metrics and by, plus any of:

  • lane: human (People), bot (Crawlers) or internal (your own team). Each metric set has a default.
  • days (calendar days ending today; 1 is today so far, default 7), or from and to (YYYY-MM-DD).
  • compare: true adds previous, the period before (a single day is compared with the same weekday a week earlier), or says why it cannot be compared yet.
  • where: filters, such as {"source": "google"}. In a query string, where.source=google.
  • sort: which count a table is ranked by, such as sessions or pageviews.

Analytics Engine keeps 90 days; past that, UsherStats answers from the daily rollups each site keeps for as long as the account exists. Hourly series and page-to-page pairs are not rolled up, so they answer only within 90 days.

curl "https://api.usherstats.com/v1/sites/$SITE_ID/stats?metrics=pageviews&by=source&days=30&sort=sessions" \
  -H "Authorization: Bearer $US_TOKEN"

The same as JSON (the form an agent's tool call takes):

curl https://api.usherstats.com/v1/sites/$SITE_ID/stats/query \
  -H "Authorization: Bearer $US_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"metrics": "requests", "by": "bot", "lane": "bot", "days": 7, "compare": true}'

A name that is not on the catalogue's lists is 400, and field says which:

curl "https://api.usherstats.com/v1/sites/$SITE_ID/stats?metrics=pageviews&by=blob3" \
  -H "Authorization: Bearer $US_TOKEN"

Many queries at once

Up to 40 named specs in one call. A spec that is refused answers {"error": {"status": 400, "title": ...}} under its name; the others still answer.

curl https://api.usherstats.com/v1/sites/$SITE_ID/stats/batch \
  -H "Authorization: Bearer $US_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"queries": {"byDay": {"metrics": "pageviews", "by": "day", "days": 30}, "crawlers": {"metrics": "requests", "by": "category"}}}'

The People summary

The People boxes as numbers: sessions, pageviews, from search, average session, bounce rate, single-page visits and pages per session, each with the previous period's figure and the change. A change carries a tone: good or bad where one direction is better (a lower bounce rate is better), flat when nothing moved.

curl "https://api.usherstats.com/v1/sites/$SITE_ID/summary?days=7" \
  -H "Authorization: Bearer $US_TOKEN"

Top tables

source, medium, referrer, campaign, page, page_type, country and device count People sessions (where each began) or, with count=pageviews, pageviews. bot, category, kind, network, path, status, cache and decision count requests; event counts events.

curl "https://api.usherstats.com/v1/sites/$SITE_ID/top/page?days=30&count=pageviews&limit=20" \
  -H "Authorization: Bearer $US_TOKEN"
curl "https://api.usherstats.com/v1/sites/$SITE_ID/top/bot?days=7" \
  -H "Authorization: Bearer $US_TOKEN"

Marking your own browser

Your team's visits belong in Internal, not People. Tools mark themselves with a signed header; a browser is marked by opening a link on your site's own first-party path (/_us/, which the Worker SDK and the first-party proxy set up). The link works for ten minutes, once per browser you open it in, and the mark lasts 90 days. POST /v1/sites/{id}/internal-link/rotate replaces the site's internal key, so every browser marked before stops counting as yours (mark them again).

The link is made only for a hostname the site has verified (its TXT record, see sites) or serves in proxy mode: it sets a cookie on that domain. Verify it first:

curl -X POST https://api.usherstats.com/v1/sites/$SITE_ID/hostnames/fieldnotes.example/verify \
  -H "Authorization: Bearer $US_TOKEN"
curl https://api.usherstats.com/v1/sites/$SITE_ID/internal-link \
  -H "Authorization: Bearer $US_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"hostname": "fieldnotes.example"}'

See also goals and experiments, bot protection, search and export.

View this page as Markdown