Analytics, and views the analyst draws

Betterloop's job is telling you what to improve - that is the insight feed. The analytics page is the layer underneath it: the same events, unranked, so you can check a finding against the traffic it came from. Next to the board is a panel that turns a question into a chart.

The board

Five views, measured from your own events over the last 7 to 14 days. Each is the same kind of object the analyst produces, so nothing on the board is privileged.

  • Sessions per day - sessions by day, last 14 days
  • Where people get stuck - rage and dead clicks by element, last 7 days, top 8
  • Errors by page - errors by page, last 7 days, top 8
  • Traffic by device - sessions by device, last 7 days, top 6
  • Slowest pages (p75) - p75 load time by page, last 7 days, top 8

The panel offers a few more that the board does not carry - busiest hours, referrers, errors day by day - so asking for a view adds to the board rather than redrawing it.

Asking for a view

Type a question and the analyst draws it. It is the same analyst that answers in Ask and over MCP, reading the same measurements - so a question about a chart and a question about a finding are one conversation, not two features that share a login.

It does not write queries

The model never emits SQL, and there is no code path where it could. It fills in a form - one metric, one grouping, optional filters, a window and a row limit - where every choice is an entry in the tables below. Anything else is rejected before a query is built. Your events live in a table shared with every other project, so the tenant scope is added by the query builder itself rather than by the caller or the model: it cannot be forgotten, and it cannot be argued out of by anything written on one of your pages.

The chart says what it counted

The analyst names a chart, because a title is presentation. It does not get to describe one. The caption under every view - errors by page, last 7 days, top 8 - is generated from the query that actually ran, so a chart titled "checkout is fine" still tells you underneath exactly what was measured.

It refuses rather than substituting

Ask for revenue by campaign and you get a sentence explaining that this data does not carry it, not a chart of something else with a title implying it answered. Declining is a first class outcome; the alternative is a product that is confidently wrong on the questions you cannot check.

What it can measure

MetricCountsMeasured over
eventseventsall events
sessionssessionsall events
pageviewspageviewsall events
errorserrorsall events
frustrationrage and dead clicksall events
vital_p75p75 load timeweb vital samples

What it can split by

GroupingSplits byMeasured over
daydayall events
hourhour of dayall events
pathpageall events
typeevent typeall events
devicedeviceall events
browserbrowserall events
referrerreferrerall events
error_messageerror messageerrors and unhandled rejections
elementelementrage and dead clicks
vitalweb vitalweb vital samples

Groupings restricted to a subset carry that restriction with them - splitting by error message counts errors, never every page view that happened to have no message. A time series keeps a zero, because the day something stopped is the point; a ranked list drops one, because a top 8 padded with pages that had no errors is a list of pages, not a ranking.

Limits

  • Window: 1 to 90 days, defaulting to 7.
  • Rows: up to 50 groups per chart, defaulting to 10.
  • Filters: one exact page path, or a path fragment, or one event type - pageview, click, rage_click, dead_click, error, rejection, vital, custom.
  • Twenty views a minute per account.

Self-hosting without an API key

The board and the saved views need no model - they are database queries, and they run on any deployment. Only the question box needs an ANTHROPIC_API_KEY, and without one it says so plainly rather than sitting there doing nothing. The insight feed is likewise produced by detectors, not by a model.