Skip to the page
Get started

Docs · Concepts

Checks and Reports

The two kinds — one compares systems, one shows a single source — and why the word "report" still appears in places.

There are two kinds of thing in the Checks tree, and the difference is decided when you create one.

#Comparison check

Lines two or more sources up on shared keys and shows where they disagree. This is what Mosaic is for, and it is what the rest of this documentation means by Check.

A Check reads an aggregation — the object that holds the keys, the measures and the Rules. Its result has matched rows, differing rows, missing rows, and a verdict.

#Flat report

One source, shown as it comes — columns, filters, schedule, exports. It compares nothing.

Because it compares nothing, a Report has no keys, no measures, no deltas and no Rules. Every row counts as a match, and the counts a comparison reports are answered honestly: total n, match n, differences 0, missing 0.

Use one when you want a query on a schedule, exported or published to people who should not have database access.

#Choosing between them

Both are created from the + menu on the Checks group, which offers exactly two entries:

EntryIts hint
Comparison checkLine two or more sources up on shared keys and show where they disagree
Flat reportOne source, shown as it comes — columns, filters, schedule, exports

#A quirk worth knowing

The sidebar still draws an Aggregations group under a flat report. You can create one there, and it will run and show a result on its own tab — but the Report's own run never reads it. Nothing is broken; the group simply is not filtered out by kind. Treat an aggregation under a Report as a scratch pad, not as part of it.

#Where the word "report" still appears

Mosaic used to call a Check a report. The word was changed everywhere a person reads it, but not in the places where changing it would break something that already works. You will meet it in five places, and each is deliberate.

1. Published addresses. A Check publishes at /checks/<slug>. A flat report publishes at /reports/<slug> — that is its proper address, not a legacy one. Either segment opens either kind, for ever, and the page corrects its own address bar once it knows which it is.

2. Old in-app links. /report/<id> is still understood and always will be. The tab rewrites the address to /check/<id> when it opens. Note that a flat report also lives under /check/<id> inside the app — an address is not prose.

3. Webhook payloads. The JSON body a notification sends has a field called report, carrying the Check's name, and a field called reportUrl. Endpoints your colleagues have already built read those names, so they stay.

4. Filename and subject tokens. The token offered is {{check}}. {{report}} is what it used to be called, is in every filename and subject saved before the change, and both work for ever.

5. A few strings that have not caught up. The empty state under a flat report's source picker reads "This report has no data sources yet." — which is correct for a Report and stale for a Check.

The API tells the same story: the client calls /api/checks/…, which is rewritten onto the registered /api/reports/… routes, so scripts written against the old paths keep working.