Reports
Reports explained
Every report the dashboard has today, the question it answers, the URL it lives at, and the plan it needs. Nothing on this page is a roadmap item.
On this page
- Why the Brief and Explore can show different numbers
- How the dashboard is organised
- Explore — the eleven views
- The event catalogue
- The per-view depth added in 7D
- Notes on a chart
- Outcomes — the four views
- Funnels
- The Brief
- Ask
- Settings, alerts and watched segments
- Alerts and incidents
- Exports
- Shared dashboards
- The plan gates in one place
All documentation
Why the Brief and Explore can show different numbers
Same metric, same project, two honest windows — and the difference is exactly one day.
Two windows, both deliberate
The Brief measures the last 7 FULL days, ending yesterday — today is excluded on purpose, because the Brief's job is comparison, and a partial today would skew every 'vs the week before' delta. Explore's 'Last 7 days' is a rolling window: the last 6 full days plus today so far, because a live dashboard that hides today would be broken the other way. The two overlap on six of their seven days, so on a busy site they will rarely show the same visitor count — and both are correct for the question their surface answers. The Brief prints its exact date span next to every figure so the two can never be mistaken for the same window; Ask's 'last 7 days' matches Explore's. On any closed range — a specific month, a fixed pair of dates — every surface agrees exactly.
How the dashboard is organised
Seven surfaces, and most reports are a view inside one of them rather than a page of their own.
The seven surfaces
Every project opens on the Brief. The other six sit beside it in the navigation. A surface is a real route; a view is a state of that route, so the browser back button, a bookmark and a shared link all behave the way you expect.
| Surface | URL | What it is for |
|---|---|---|
| Brief | /project/{id} | The home screen. What changed since you last looked, ranked, with the evidence and a pre-filled action under each item. |
| Explore | /project/{id}/explore | One instrument, eleven subjects. Where you go to ask about traffic, sources, devices, pages, speed and behaviour. |
| Realtime | /project/{id}/realtime | Who is on the site right now, and the events landing as they land. |
| Outcomes | /project/{id}/outcomes | The four reports about results rather than traffic: goals, funnels, retention and revenue. |
| Impact | /project/{id}/impact | The ledger of closed cases: what Coruve caught, the drafted fix, and the verified before/after recovery. Recovery figures are estimates — direction, not accounting. |
| Ask | /project/{id}/ask | A plain-language question about your own site, answered by a deterministic query with the matching report one click away. |
| Settings | /project/{id}/settings | Project setup, watched segments and alerts, team, billing, and the history importers. |
A view is a query parameter
Explore — the eleven views
Each one answers a different question about the same traffic, under the same date range and the same filters.
What each view answers
The rail down the left of Explore switches subject without losing your range, your filters or your comparison. Add ?view= to the Explore URL to open one directly.
| View | ?view= | The question it answers | Plan |
|---|---|---|---|
| Overview | overview | How much traffic, from where, to which pages — the default view. | Every plan |
| Acquisition | acquisition | Which channels, sources and campaigns brought people, and how each one performed. | Every plan |
| Locations | locations | Which countries, regions and cities visits came from. Derived from the IP at the moment of the request, which is never stored. | Every plan |
| AI Traffic | ai | How much of your traffic is people, AI assistants and ordinary crawlers, which assistants, and how each visit was identified. | Every plan (quality layer Starter and up) |
| Devices | devices | Desktop, mobile or tablet; which browsers and operating systems. | Every plan |
| Journeys | journeys | The paths people actually take through the site, forwards or backwards from any page you anchor on. | Every plan |
| Frustration | frustration | Where people got stuck: rage clicks, dead clicks and quick backs, by page and by source. | Starter and up |
| Sessions | sessions | Session shape — how long, how many pages, which pages people entered and left on. | Every plan |
| Events | events | The event catalogue: every behaviour Coruve has catalogued on your site with its kind, its counts and sessions for your range, when it was last seen and how it trends. See The event catalogue below. | Every plan |
| Site Health | health | Real-user speed measured in your visitors' browsers — TTFB, FCP, LCP, INP, CLS — worst pages first. | Every plan |
| Maps | maps | Where people click on a page and how far down they read, as a density grid rather than a screenshot overlay. | Starter and up |
Why Maps is not called Heatmaps
The AI Traffic view is deliberately split in two
The human / AI / crawler breakdown, the list of assistants and the trend over time are on every plan, including Free — knowing an assistant sent you traffic is table stakes for a product partly named for it. So is the methodology split that says how each visit was identified — Verified (a cryptographic signature checked against the AI company's own published key), Inferred (the visit said so, through its user agent or referrer) and Unattributed (automated, but matched to no product). That split is not sold as an upgrade, on purpose: it is how the numbers above it were arrived at, and a product does not charge for the truthfulness of its own reporting. What Starter and up adds is the quality layer — the conversion multiplier and the per-assistant and per-channel tables.
What counts as a step in a journey
A step is either a page somebody viewed or an event your own site tracked — checkout_start is as much a step as /pricing is. Two kinds of row are deliberately not steps: Coruve's own instrumentation (the scroll and speed beacons the snippet fires, which nobody chose to do), and the clicks captured automatically on every button and link, which would otherwise turn almost every path into a list of clicks. Two views of the same page in a row count once, so a single-page app re-rendering does not invent a step.
Path rules are applied when a journey is read, in one fixed order
Dynamic paths are masked first (if you have that switched on), then any page you have excluded is dropped, then any section you have collapsed becomes a single step. Excluding before collapsing is what makes the two rules independent — the other order would let a rule folding /blog into one step hide a page you had asked to exclude by name. None of this rewrites what was stored, so a rule you add today reshapes last month's paths, and deleting it puts them back on the next load.
Journeys is on every plan; the behaviour maps are not
Journeys used to be Starter and up. It is not any more (revised 2026-08-11): where people go from one page is a question about your own site, and what a plan buys is how much of the analyst's work Coruve does with the answer — not which of your own numbers you may look at. Frustration and Maps (the click-and-scroll report) moved the other way, to Starter and up, for the same reason read in reverse: those two are Coruve examining behaviour rather than counting visits. Both are enforced server-side in the action that fetches the report and again in the CSV export route, so the gate is not something the interface can be talked out of.
The event catalogue
What Coruve worked out your site does, so you can build a goal on a button without knowing what the button is called.
It is the rows of Explore ▸ Events
The Events view is the catalogue. Each row is one behaviour with its kind, how many times it fired and in how many sessions over your range, whether those sessions also reached your goal, when it was last seen, and its trend — with the change against the previous period when comparison is on. Categories group the rows rather than filling a column. Three things feed the list: items the catalogue derived, labels you approved, and raw event names the store counted in this range but has not catalogued yet, so nothing your site sends can hide from this screen. Page views are the one exclusion — they are the whole of the rest of the product.
One picker, four places you name a behaviour
Goals, funnel steps, alert metrics and a segment's behaviour conditions all open the same catalogue picker, and the Events view itself opens it to define something narrower than a row. The point of it is that you never type an event name: you pick the button, form or event from a list Coruve built by watching the site, and what gets saved is the catalogue item's identity, not a string you had to spell correctly. A goal on a button is genuinely a goal on a button — you still name the GOAL, because that name is what appears on your reports, but you never name the event.
Ask does not use the catalogue
Derived nightly, with floors, and capped
The catalogue is rebuilt once a day at 03:00 UTC, staggered so projects do not all run at once, over the last 30 days. A behaviour has to earn its row: at least 5 sessions AND at least 20 events before it is derived at all. Being derived is not the same as being suggested to you — for Coruve to PROPOSE something (a goal worth creating, a name worth accepting) it needs 25 sessions or 50 events. A project carries at most 200 automatically derived items and 400 in total, so a site that fires a distinct event per row of a table does not turn the catalogue into a second copy of its database.
Automatic names are offered before they are applied
Naming reaches three kinds of item — an element, a form, and your own custom events — and nothing else. Below a confidence of 0.6 the suggested name is not used: the item keeps a plain descriptive name and the suggestion sits beside it as something you can accept or dismiss. That is the whole rule, and it is why the catalogue does not quietly rename your checkout button to something a model guessed.
What you can change, and who can change it
Rename an item, define one more precisely, hide one you do not want to see, merge two that are the same thing, or dismiss a name that was offered. All five are owner-and-admin only; every member can READ the catalogue, which is what makes the picker work for everyone. Hiding is about your own screens — see the note on annotations below for the same distinction applied to chart markers.
The per-view depth added in 7D
Seven additions, and each one lives on named views rather than everywhere — which is the part worth knowing before you go looking for it.
Where each one is
None of these is a new report. Each is a panel inside an existing view, and each is on the views where the question it answers is actually asked.
| Panel | Where | What it does |
|---|---|---|
| Hour-by-weekday grid | Explore ▸ Overview and Sessions | Seven rows by twenty-four columns: when in the week your traffic actually happens. The cells are deliberately not links — there is no hour-of-week filter in the product, so a clickable cell would promise a view that does not exist. |
| Session shapes | Explore ▸ Sessions | The common shapes a visit takes, ranked: where it entered, where it left, and how many pages were in between as a band. It is an aggregate, never a list of sessions and never the route between the two ends — Coruve does not offer a session replay and this is what stands in its place. Rare shapes are withheld below a small-numbers floor. |
| Device tabs | Explore ▸ Maps | All, Desktop and Mobile. There is no Tablet tab — tablets are counted in All. The Mobile tab is removed rather than greyed out when there are too few mobile sessions on that page to draw anything honest. |
| Diverging comparison | Explore ▸ Maps | With comparison on, the click grid switches to a diverging scale reading in percentage points: colder where a cell lost share, warmer where it gained. There is no chooser for it — turning comparison on IS the mode. |
| Vitals decomposition | Explore ▸ Site Health, in the Explain drawer | Why a vital moved, split by page, device and country. It splits the COUNT of poor-rated loads and never the p75, because a percentile cannot be decomposed and the count under it can. The table on the view itself still shows p75s — it is the explanation that is count-only. |
| Segment A vs B | Explore ▸ Overview | Two saved segments on one chart. Two is the limit and the control says so; a third line stops being readable. Overview only, and setting it clears period comparison — you compare against another segment or against another period, never both at once. |
| First vs last touch | Explore ▸ Acquisition | Which channel started a visit and which one it converted under, WITHIN a single visit. Not across visits: the anonymous visitor identifier rebuilds every UTC day, so a touch last week and a purchase today cannot be joined. This is the attribution the identity actually supports, and the product does not offer the one it does not. |
Notes on a chart
Why the line moved, written down beside the line.
What they are
A note is a dated sentence drawn on a chart: a deploy, a campaign, a content change, an incident, an experiment, a change to what is being tracked, or a plain note. Owners and admins write them; every member reads them. They can be a moment or a span of days, and a note whose exact time was never recorded is drawn as a day rather than being printed at 00:00 — a precision nobody measured.
The glyph is a letter, on purpose
Each category has a single-letter marker rather than a colour of its own. Colour alone fails in greyscale, on a printout, and for a good share of readers; a letter survives all three. The letter is the same everywhere the marker appears.
Machine markers, and what 'hidden' means
Coruve writes notes too — when an alert opened an incident, when a deploy or incident webhook fired, when a history import landed, when a case was verified, when a spike was detected, and when the system changed what it was measuring. Some of those are marked hidden, and hidden means QUIET, not absent: the charts leave them off so the timeline stays readable, the analyst reads them regardless when it explains a change, and ?markers=all on an Explore URL is the real switch that brings them back. A note the chart does not draw is still a note that shaped the explanation you were given.
They draw on three views, not eleven
Overview, Frustration and AI Traffic carry the marker layer. The other eight Explore views do not, and Overview is the only one where a note can be created or deleted. This is worth knowing before you go looking for a marker on Devices: it is not missing, it was never drawn there.
Team notes only, and the WHERE clause is the promise
Every note Coruve stores today is a team note. The read paths that leave this project — the findings engine, the read API, the emails — are each scoped to team notes in the database query itself rather than filtered afterwards, so a private note could never reach any of them by accident. Shared dashboards are stricter still: hidden machine markers are left out of a public share entirely.
Outcomes — the four views
Results rather than traffic. Same URL, selected with ?view=.
What each view answers
Outcomes opens on Goals. Every view here reads the same date range and filters as Explore, so a segment you set in one carries into the other.
| View | ?view= | The question it answers | Plan |
|---|---|---|---|
| Goals | goals | How often each goal converted, and what each conversion is worth if you gave it a value. | Every plan |
| Funnels | funnels | Where people fall out of a sequence of steps you defined. | Every plan (3 funnels on Free, Infinity on Growth) |
| Retention | retention | Whether your IDENTIFIED users come back, by cohort. See the note below. | Every plan |
| Revenue | revenue | What the money did, and which sources it can honestly be credited to. | Pro and up |
A behaviour condition counts sessions, and says so
A saved segment can say more than “visits from Germany”: it can say “sessions that started checkout at least once and never bought”, or “sessions that landed on /pricing” — up to three such conditions, all required together. The word is sessions everywhere, and that is not a stylistic choice: Coruve keeps no durable identity for a person, so it cannot honestly say “visitors who did X”, only that there was a visit in which X happened. Such a segment covers at most 92 days at a time, because judging it means building a list of every matching session and there is a size past which that list stops fitting — you are told to narrow the range rather than handed a silently shortened one.
Customer value is grouped by the month somebody first paid
The group a customer belongs to is set by their first day with money actually taken — so a history that opens with a refund is not an acquisition, and somebody whose only record is a refund was never a customer at all. Each month after that shows what the group is worth per customer, cumulatively, in US dollars converted at the ECB day rate. Refunds land in the month they happened rather than the month of the charge they reverse, which is why the line can go down. Two limits bound what you see, and they are different numbers: the report shows the last SIX acquisition months as groups, and each group is followed for at most TWELVE months from its first payment. A customer's fourteenth month is not on the chart and is not withheld for a reason — the curve simply stops at twelve.
An unfinished month is drawn as unfinished
A month that has not ended yet is a partial sum, so the line stops solid at the last complete month and continues dotted — it is never filled in with today's running total pretending to be a whole month. A group of fewer than ten paying customers shows its counts and its total but not its average, because an average over nine people invites more confidence than it can carry.
Retention needs identify(), and says so instead of guessing
Coruve's anonymous visitor identifier is a one-way hash that contains the calendar day, so it changes at midnight UTC and a visitor who comes back tomorrow looks like a new one. That is the cookieless trade working as intended, and it means return visits are NOT measurable on anonymous traffic — not approximately, not with a model: the information does not exist. So the Retention page does not draw a grid of it. Where your site calls identify(), Coruve stores a one-way hash of the user id you passed, and that identity is durable — which is what makes real cohorts possible for the people who have an account with you. The page always prints what share of the range's sessions were identified, because a figure about your logged-in users is not a figure about your whole audience. Below a twentieth of your traffic, or fewer than twenty identified users, it shows a card explaining why instead of a grid. Cohorts under twenty users keep their counts and lose their percentages, and periods that have not finished yet are shaded rather than counted as nobody returning. First-seen is judged against the previous 90 days, or your plan's data retention if that is shorter.
What 'Visitors' counts
Visitors counts distinct daily visitor identifiers. The identifier is a one-way hash of the site, the calendar day (UTC), the browser's signature (user agent, language, timezone) and the network address, computed on our servers and never stored in reversible form; the address itself is not stored. Because the day is part of the hash, the same person is a new visitor every day, and we do not know whether anyone came back. Before 2026-08-26 the network address was not part of the hash, so visitors on very common browser set-ups were undercounted; from 2026-08-26 the counts are higher and more accurate. Sessions and everything measured per session did not change.
Revenue is Pro and up, and so are its connectors
The revenue report, the Stripe Connect integration and the Shopify integration all read one flag — revenue tracking — which turns on at Pro. One flag rather than three is deliberate: a plan where you could connect Stripe but not read the report it fills would be a setup flow that ends at an upgrade wall. The live webhooks are the exception and are not gated, so a downgrade stops the reports being readable without losing payments your store is actively reporting. How a payment is credited to a source is its own reference: see Revenue attribution.
Funnels
A sequence of steps, and the two honest readings of what 'in order' means.
Building one
Between two and ten steps, picked from the event catalogue — so a funnel is built out of the same buttons, forms and events the rest of the product knows about, and no step is a string you typed. Ten is not a product opinion: the query engine behind it takes ten conditions.
Two readings, and why both are shown
The headline number is the IN ORDER reading: the steps happened in this sequence, and other things may have happened in between. Underneath it, when the two disagree, sits the EXACT ORDER reading: the steps happened back to back with nothing in between. When they agree the card says so in one line rather than printing the same figure twice. This exists because the card once labelled its default reading 'any order' while computing the in-order one — a word about the numbers that the numbers did not support. Naming both readings, and printing the second whenever it differs, is what replaced that one wrong word.
The conversion window is clamped to 24 hours
You choose how long someone has to complete the funnel, but the figures use at most one day, and the card says so when your saved window is longer. The reason is the same one that shapes retention: the anonymous visitor identifier is rebuilt from scratch at UTC midnight, so nobody can be followed from Monday into Tuesday. A funnel offering a 7-day window would be offering a number it cannot measure. The window is resolved once and every figure on the card — including the drop-off story — uses that same resolved value.
The device breakdown, and where it goes
A funnel can be broken down by device, and the breakdown is computed under the primary reading only — one reading, so the split adds up. It is worth knowing when it appears: it is requested on the first load of the view, and changing the range or switching funnel in the browser re-runs the funnel without it, so the device clause disappears until the page is loaded afresh.
The drop-off story is deliberately ephemeral
Asking what people did instead of taking the next step produces a story on screen and writes NOTHING: no finding, no saved view, no ledger entry, and no URL that reproduces it. Reload and it is gone. The only writes in the whole feature happen when you press a button in it — create an alert, save a segment — which is the difference between a tool that answers a question and a tool that quietly accumulates state you did not ask for.
The Brief
The home screen, and the only report that decides for itself what to show you.
What it is
The Brief is a ranked feed of findings a deterministic engine computed — this metric moved against its own history, this one crossed a threshold we treat as a floor. Each card carries the numbers, the segments that moved, and pre-filled buttons (create an alert, save a segment, add a note). A sentence over the evidence may be written by a language model, and when there is no model available a template sentence renders instead and every number is unchanged.
What your plan changes about it
Three things, and none of them is access — the Brief is on every tier. First, cadence: on Free, findings appear on a weekly cutoff rather than as they land, and the Monday email follows the same clock. Second, which families of finding are computed for you at all. Third, how many fixes Coruve will follow through verification at once — one a week on Free, five open at a time on Starter, unlimited above.
| Signal family | Covers | Plan |
|---|---|---|
| Traffic | Visits, sessions, sources, pages | Every plan |
| Goals | Goal conversions and their movement | Every plan |
| Experience | Frustration signals — rage clicks, dead clicks, quick backs | Starter and up |
| Speed | Real-user web vitals | Starter and up |
| Cohort | Retention and returning-visitor health | Starter and up |
| Money | Revenue findings | Pro and up |
| Combined | Findings that join two or three signals into one claim — a page that got slower, is frustrating people, and is costing money | Pro and up |
Ask
A question in plain language, answered from your own data.
How it answers
Your question is routed to one of a fixed set of measurements, that measurement is run as an ordinary query, and the answer card prints the rows and the numbers it found. A model writes the headline sentence over that card and chooses which measurement to run — it never invents a figure, because every number on screen came out of the query, and the sentence is checked against the answer before it is shown. The buttons under the answer open the matching report with the same range and filters already applied.
Every plan can ask; the ceiling is what scales
The limit is per project, per rolling day, and it is enforced server-side. The surface tells you how much of it you have spent.
| Plan | Questions per day |
|---|---|
| Free | 3 |
| Starter | 50 |
| Pro | 300 |
| Growth | 1,500 |
Your question text never leaves the query layer
Settings, alerts and watched segments
11 sections in two groups, selected with ?section=.
The sections
Settings is a surface like any other, so /project/{id}/settings?section=billing is a link you can bookmark. The rail splits in two: seven sections configure THIS PROJECT, four belong to the workspace around it. The five keys that existed before the redesign — project, saved, alerts, team, billing — are unchanged, so every link ever sent still resolves; the other six are new.
| Section | ?section= | Group | What is there | Plan |
|---|---|---|---|---|
| Project | project | Project | The project's name, domain and timezone, and the install check that confirms the snippet is reporting. General settings only — everything this row used to list has moved to a section of its own. | Every plan |
| Tracking | tracking | Project | Traffic exclusions — your own visits, and rules for anyone else — plus dynamic-path masking, journey path rules, and which tracker version your site is measurably running. Bot filtering lives here too, as a statement rather than a switch: known crawlers are dropped before ingest on every project and there is nothing to turn off. | Every plan |
| Privacy & data | privacy | Project | Data retention (a statement of your plan's window, not a picker), location granularity, Do Not Track and GPC, and Erase history — a permanent purge of every event before a date you choose. | Every plan |
| Notifications | notifications | Project | Who gets emailed, the Slack incoming webhook alerts post to for the whole project, and quiet hours — overnight notifications are held and delivered on the first check after they end, never dropped. | Every plan |
| Data & export | export | Project | One-time export, the scheduled export email, the GA4 and Plausible history importers, and the Stripe and Shopify revenue connections. | Every plan (importers Starter and up; revenue connections Pro and up) |
| API keys | api | Project | API keys — the ingest key that sends events in, and the read key that reads numbers out — and share links, which are the other way a number leaves this project. | Every plan (read keys need Pro) |
| Danger zone | danger | Project | Transfer the project to another owner, or delete it. The two changes that cannot be undone. | Every plan |
| Watching & saved | saved | Workspace | The ledger of segments, goals, funnels and alerts, with when each was last used. Filters and ad-hoc questions never appear here — those are scratch, and scratch does not accumulate. | Every plan (3 saved segments on Free) |
| Alerts | alerts | Workspace | Alert rules and the incidents they opened. Alerts reach you by email and by Slack, and the section below explains what an incident is. | Starter and up |
| Team | team | Workspace | Members and invitations. | 1 member on Free, up to 25 on Growth |
| Billing | billing | Workspace | Plan, usage against your event allowance, and invoices. | Every plan |
A section key is never a 404
Exporting what you are looking at
Every report exports on every plan including Free, and it exports the report AS FILTERED rather than the whole dataset — since 7D the file honours the same filter operators and the same ?segment= as the screen you were looking at, where before it silently answered the unfiltered question and totalled differently. CSV and JSON are both served by the same route (format=csv is the default; anything that is not exactly json is treated as CSV). The route re-checks the same plan gates as the report itself — the click-map and scroll-map exports refuse below Starter, the revenue export refuses below Pro — so an export cannot be used to walk around a gate.
The read API is a different door, not a different format
This page used to say that reading reports back as JSON was the read API's job. It is not: the export route serves JSON directly, to a person signed in with a browser session. What the read API adds is a KEY — a credential a script can hold, with its own rate limit, its own plan gate (Pro and up) and a stable envelope. Same numbers, two doors: the export is session-authenticated and one file at a time; the API is key-authenticated and built to be called. See the Read API reference for the endpoints.
Alerts and incidents
A line you name in advance, and the record of every time it was crossed.
A rule, and what it can say
An alert watches one metric — visitors, sessions, an event, a goal, or an item from the event catalogue — over an hour or a day, scoped to any filter or saved segment. It can carry up to three conditions combined with ALL or ANY, so 'traffic fell and the goal fell with it' is one alert rather than two. It can also carry up to four notification windows: a stretch of the week with its own threshold, or with no threshold at all, which means do not evaluate here. That is how 'weekends are different' and 'do not measure me during the nightly batch' get said without turning the alert off.
How often it is actually checked
The sweep runs every five minutes. An alert measured over an hour is evaluated on every sweep; an alert measured over a day is evaluated at most every fifteen minutes, because re-reading a whole day sixty times an hour costs a great deal and tells you nothing new. A rule does not fire the first time it crosses — it has to stay crossed for the number of checks you set — and it does not recover on the first check back either, with a small margin the other side of your threshold so a metric sitting exactly on the line does not flap.
An incident, and the numbers frozen inside it
The crossing opens an INCIDENT, and the evidence is measured once, at that moment, and stored on it. Nothing re-reads it afterwards: the email, the Slack message and the drawer in Settings all print the same figures under the words 'as measured at', with the time they were taken. That is the difference between an alert and a report — a report tells you what is true now, an incident tells you what was true when it tripped, and a number that quietly updates itself between the notification and the investigation is the reason the two disagree in every product that lets it happen. Incidents also carry a de-duplication key with a unique index behind it, so two sweeps racing each other produce one incident and one notification rather than two.
'Deviates from usual' says which usual
A threshold you type is unambiguous. A rule that watches for a deviation is not, so it names its own basis rather than leaving you to infer it: either the same weekday in recent weeks, or the trailing seven-day median. The trailing median will not speak until the project has three weeks of history behind it — under that it is a median of noise, and the alert says it is not ready instead of firing on one.
The simulator says 'would have', never 'will'
Before you save a rule you can run it against the last thirty days and see how often it would have fired. The result is labelled 'Simulated before save' and phrased in the past conditional throughout. It is a check on your threshold, not a forecast, and the product refuses to word it as one.
Delivery: email and Slack
Alerts reach you by email and by Slack. Slack is a project-level incoming webhook you paste in under Notifications, which covers every alert on the project; an individual alert can override it with its own. An alert with neither an email recipient nor a webhook is HELD rather than silently discarded, and the reason is recorded on the incident. Quiet hours hold overnight notifications and deliver them on the first check afterwards — held, never dropped.
The buttons in a notification are signed links
Acknowledge and 'mute for 7 days' are the only two actions a notification carries, and both are signed with an HMAC that expires after seven days. Following the link only ever shows a confirmation page — clicking through a link preview, a security scanner or a corporate mail proxy changes nothing, because nothing changes until the form on that page is submitted. The endpoint is rate-limited per address and fails closed: if it cannot check the limit, it refuses.
The digest re-states; it never re-measures
A digest gathers the incidents that already happened and prints each one's frozen summary. It does no arithmetic across them and no new measurement of any of them — even the subject line declines to say 'three alerts', because a count in a subject is a number the reader will check against the body.
What the incident chart can and cannot show you
The small chart in an incident is DAY-GRAIN, always, and its caption says daily. An alert measured over an hour therefore gets a coarser picture than its own rule, and reading a smooth daily line as minute-by-minute would be reading it wrong. It also draws no threshold line at all — not the frozen one and not today's — because the series follows the rule as it is configured NOW, and a rule edited after the fact would otherwise put a marker exactly where the incident never crossed. The frozen numbers above the chart are the record; the chart is context.
Exports
One report, every report, or every report every Monday morning.
Three shapes
A single report as CSV or JSON, or report=all — a zip of every report your plan includes, with a README that explains what each column means and names anything left out, empty, or failed. The zip is always a zip; a format on that request is ignored. Everything obeys the filters and the saved segment you had applied, and the same plan gates as the report on screen.
Or have it arrive on its own
Settings ▸ Data & export will send the bundle by email — weekly, monthly or daily — at 07:00 in the PROJECT's own timezone rather than yours or ours. A sweep runs every 15 minutes and sends whatever has come due — an interval rather than a fixed clock time, precisely because 07:00 means a different instant in every project.
Five rules a scheduled export keeps
Never a partial period: a weekly export covers the last COMPLETE week, so the file never contains a half-finished Monday. Never more than your plan shows on screen. Never stamped as sent when it failed — the record only moves when a run finished, so a failure is retried rather than skipped. One project's failure never stalls the run: each project is attempted on its own and a broken one is counted and stepped over. And a period with nothing in it is recorded as a quiet period, with the stamp written and no email sent — you are not emailed an empty spreadsheet, and the schedule does not spend the next run trying to catch up on a week that had no traffic.
The one hour a year the clock moves
The send time is the period's end plus 7 hours rather than a time asked of the calendar. In a timezone whose spring-forward swallows 07:00, the export arrives an hour later that day instead of the period being skipped. Late once a year beats missing.
Big bundles become a sealed link
Up to 8 MiB the bundle is attached to the email. Over it, the email carries a link instead, and that link is built to be handled carefully: it is single-use and claimed atomically, so a mail scanner that follows it cannot spend it twice; it expires after 24 hours; it is never cached and never indexed; it is rate-limited by address and fails closed; and a token that is unknown, already used, or expired all give the same answer, because telling them apart would tell someone which tokens are real. The link itself is 32 random bytes and only a hash of it is stored, so a leaked database does not hand over anybody's reports.
The ceilings
A bundle you download from the browser is capped at 16 MiB compressed and 64 MiB of CSV before compression; past that the download is refused, with the size in the message and two ways round it. An emailed bundle is bigger — 64 MiB compressed and 256 MiB of CSV — because it is assembled away from the app rather than while you wait. A single request may span at most 366 days, and the exports with no natural top-N of their own — the retention grid in particular — stop at 5,000 rows. A truncated file says it is truncated in the README rather than ending mid-table.
How often you can ask
Exports are rate-limited, per address and per project, at levels far above real use — 60 exports an hour for a project, of which 12 may be whole-plan bundles. A handful of whole-plan bundles can also be building at once across the whole app, so a very busy moment answers "try again in a moment" rather than slowing everybody's dashboard. Hitting either of these by hand means something is looping, not that you are working hard.
The plan gates in one place
Every gate that exists today, and nothing that does not.
What each tier adds
Gates are enforced in the server action, in the export route and in the background worker — never only in the interface. A gate checked where the button is, is a gate that expires the moment a job runs after a downgrade.
| Capability | Free | Starter | Pro | Growth |
|---|---|---|---|---|
| Brief, Explore, Realtime, Outcomes, Ask, CSV export | Yes | Yes | Yes | Yes |
| Journeys, segmentation, suggested goals & funnels | Yes | Yes | Yes | Yes |
| AI traffic split, sources, trend and methodology | Yes | Yes | Yes | Yes |
| Site Health | Yes | Yes | Yes | Yes |
| Brief cadence | Weekly | Daily | Daily | Daily |
| Saved segments | 3 | Unlimited | Unlimited | Unlimited |
| Fixes tracked to a verdict | 1 / week | 5 at once | Unlimited | Unlimited |
| Things Coruve keeps watching | 0 | 5 | Unlimited | Unlimited |
| Shared dashboards | 1 | 5 | Unlimited | Unlimited |
| Frustration and Maps | No | Yes | Yes | Yes |
| AI traffic quality layer | No | Yes | Yes | Yes |
| Alerts | No | Yes | Yes | Yes |
| Import history from GA4 or Plausible | No | Yes | Yes | Yes |
| Impact ledger and combined findings | No | No | Yes | Yes |
| Revenue report, Stripe and Shopify | No | No | Yes | Yes |
| Read API | No | No | Yes | Yes |
| Shared dashboards without Coruve branding | No | No | No | Yes |
| Events per month | 10,000 | 100,000 | 1,000,000 | 5,000,000 |
| Projects | 1 | 3 | 10 | Unlimited |
| Funnels | 3 | 25 | 100 | Unlimited |
| Data retention | 30 days | 365 days | 730 days | 1,095 days |
| Ask questions per day | 3 | 50 | 300 | 1,500 |
Retention is a deletion promise, not a paywall