A session means the same thing everywhere
Every source normalises into one schema on the way in, so comparing two brands is valid by construction rather than by whoever built the spreadsheet remembering to make it so.
The problem
GA4 counts a session one way, Search Console counts a click another, and neither will tell you what happened across both. Put two brands side by side and you are comparing two definitions, not two numbers, and nothing in either tool warns you.
What we mean
A semantic layer sits between the warehouse and everything that reads it. Measures and dimensions are declared once, with the source each one comes from and the grain it is valid at. Nothing, not a chart, not the chat, not the API: can ask for a number the layer has not defined.
1
definition of a session, across every brand
How it works
Start to answer
- 01
Sources land raw
Each connector writes what its provider actually returned, unmodified, so the original is always recoverable.
- 02
Normalised on the way in
Day boundaries, channel names, URL shapes and country codes are reconciled at ingest rather than at read time.
- 03
Declared as measures
Each measure names its source, its aggregation and the dimensions it is valid against.
- 04
Everything reads the layer
Charts, chat, the API and the MCP server all go through it. There is no second path to the numbers.
Before and after
What actually changes
Before
You export two properties, notice the totals disagree, and spend an hour deciding which one to trust before you can even start the analysis.
After
Both brands are already on the same axis. The comparison is the first thing you do, not the last.
Before
A figure in last quarter's deck cannot be rebuilt because nobody recorded which filters were applied.
After
Every chart is a saved query. Open it and you can see exactly what was asked.
Declared, not inferred
The schema is a contract, not a convention.
- Every measure names its source
- Dimensions declare the grain they are valid at
- Invalid combinations are refused, not silently averaged
Readable by machines
The same definitions the UI uses are available over HTTP and MCP.
- GET /api/schema returns the whole layer
- The MCP server exposes it as get_metric_schema
- Clients cannot invent a metric name
Honest about gaps
Where a source has not reported, the layer says so.
- Missing days are absent, not zero
- Revised days are re-pulled rather than trusted once
- Partial windows are labelled as partial
Why the layer sits below the chat
The model chooses the question. The schema decides what the numbers mean. Keeping that split is what makes an AI answer auditable: the model cannot invent a metric, only select from ones that already have a definition, and the query it selected is shown alongside the answer.
What it refuses to do
It will not average a rate across brands of different sizes and present the result as a portfolio figure, and it will not join two sources at a grain where the join is not valid. Both are easy to render and neither means anything.
In short
Comparisons between brands stop being an act of faith. The definitions are applied once, at ingest, and everything downstream inherits them.
More features
Portfolio view
The brand index does not average your portfolio into a single score nobody can act on. It sorts by movement and flags what needs you.
Ask in plain English
Ask which brand lost the most organic traffic last month. Get the answer, the chart, and the exact query that produced both.
Charts & dashboards
Every chart is a saved query rather than a picture, so a dashboard is a set of live questions instead of a set of stale images.
See the whole brand
Search, analytics, ads, revenue, CRM and support, pulled into one view per brand and kept current. Connect the first source in a few minutes.