Feature

One link per client, and nothing else on it

Tick the sites that belong to a client, copy the link that appears, send it. They open a page with their own sites on it, in read-only, with no account and no seat to pay for. Everything below is what that costs you and what it cannot do.

What the client opens

A single page, no navigation, no vocabulary they would have to learn. It answers the three questions a client actually has, in the order they have them: is my site working, has it been working this month, and when was it not.

  • A banner at the top that says all fine, or names how many of their sites are not answering.
  • One row per site: name, domain, a status dot, a bar chart of the last twenty-four hours, and the thirty day availability as a percentage.
  • A table of recent interruptions: which site, when it started, how long it lasted, and whether it is over.
  • One sentence saying that a single failed measurement is not counted as an interruption, because that is the question a client asks the first time they see the table.

A paused monitor shows as paused rather than as a failure. Monitoring you suspended on purpose is not an incident for the person paying for the site, and counting it as one is how a report loses its reader.

What decides the colour of a dot is on the other side of the wall, and it is a longer story: what the engine watches on the page, and what it does when it changes.

A client space: a status banner, one row per site with its thirty day availability, and a table of recent interruptions
The whole page. There is no second screen behind it.

What the link cannot show them

This is the half that decides whether you send the link at all. An agency is not unsure about the value of a client dashboard; it is unsure about what the dashboard leaks.

What a client link shows, and what it withholds
What On the client link Why it is that way
Any site belonging to another client Never Each read carries the client id in the query. There is no list to filter down to.
Your monitor settings, thresholds and alert rules Never The client screen renders no form and no configuration at all.
Who else you watch, and how many Never The failure counter in the page header is theirs, not the portfolio total.
Any way to change anything None Every write action lives behind the login and a CSRF token, so a link cannot reach one.
Their own history after you rotate the link Kept The history hangs off the client record, not off the token that opens it.

The last row is the one people get wrong when they build this themselves. If the history is keyed on the credential, rotating the credential throws away the twelve months of availability you were about to invoice for.

The separation is in the query, not in the page

Most read-only dashboards are a normal dashboard with things hidden. That works until one request forgets to hide something. Here the filtering happens before the data leaves the database, so there is nothing to forget.

Every read carries the client id

This is the query behind the list of sites, copied from the engine rather than described:

SELECT s.id, s.name, s.domain, s.cms, m.status, m.uptime_30d, ...
FROM sites s
LEFT JOIN monitors m ON m.site_id = s.id AND m.role = 'primary'
WHERE s.client_id = ?
ORDER BY s.name ASC

The same clause appears in the overview, in the incident list and in the monitor ids used for the little bar charts. The value bound to that placeholder comes from the client record the token resolved to, never from the request. There is no parameter on the page to tamper with, because the page reads none. Read src/Client.php.

The client space is served before the login exists

In the engine front controller, the block that answers a client link runs and exits before the session is even started. Access without an account is not a tolerance carved out of the admin area: it is a separate path that never reaches the admin area at all. Nothing behind the login can be reached from it, because the code behind the login has not run.

An unknown token, a malformed one and a disabled one all produce the same 404 with the same body. Distinguishing them would turn the page into a way of finding out which tokens exist.

What the test suite holds in place

The engine ships its own runner, and the section covering this feature runs 42 checks out of 808, counted by running it on 1 August 2026 rather than by reading a number off a page. Nine of them are malformed tokens, including an SQL fragment, a path traversal and the right token in the wrong case. The others cover the parts that are easy to get wrong later: reattaching a site moves it instead of duplicating it, rotating a token detaches nothing, deleting a client keeps its sites and their history.

Run it yourself: bin/selftest.php, section Mode agence. It needs no dependencies and no Docker, which is the same reason the engine runs on shared hosting.

What the other seven answer to this

The usual answer to the same need is a status page, and a status page is a genuinely different object: it is public, it is one page for everybody, and one of the seven makes a much better one than we do. A scoped link is the other shape of the answer. An agency normally wants the second, and a client with a compliance page in mind wants the first.

What each compared tool offers for showing one client their own sites
Tool Their answer, as read on their own page Read on
UptimeRobot No dated reading on this point Not read
Uptime Kuma Status pages 2026-07-29
Better Stack No dated reading on this point Not read
StatusCake No dated reading on this point Not read
Pingdom No dated reading on this point Not read
Site24x7 Not announced 2026-07-29
Hyperping Status pages 2026-07-29
UptimeEZ One link per client, scoped to their sites, no seat to pay for The source

Four of the seven carry no reading on this point, and that is a gap in our notes rather than a finding about them: UptimeRobot, Better Stack, StatusCake, Pingdom. Not announced is not the same as cannot do it, and no reading taken is weaker still. Anyone who can point at a page saying otherwise should, including in their favour.

All seven side by side, on fourteen criteria, or how to test a monitoring tool before you trust it.

Why this is the line that changes a portfolio

Thirty client sites is about ninety monitors, and on most plans a client who wants to see their own site is either a seat or a status page you have to design. Both turn every new client into a purchase decision, which is the quiet reason agencies stop adding sites to their monitoring.

The link also answers a message rather than a requirement. It is what you send when a client asks whether it is fixed yet, and that message is the one that interrupts whatever you were doing. Sending a link once is cheaper than answering it thirty times.

There is a monthly report to go with it, sent per client and covering only their sites, in the same ten interface languages as the rest of the engine. It exists for the same reason: monitoring nobody sees is monitoring nobody pays for. src/Report.php.

What the hosted plan costs, with nothing counted

Questions people ask before sending the first link

Does the client need an account?

No, and there is nothing to create on their side. The link is the whole credential: they open it and the page is there. That is deliberate, because the alternative is an invitation to chase, a password to reset on a Sunday, and a seat to pay for on most plans.

If the link is the password, what happens when it leaks?

You rotate it, from the client screen, and the old one stops working on the next request. Nothing is lost: the history, the sites and the monitors are attached to the client record, not to the token. There is also a switch that closes the space while keeping the link, for a client whose contract is paused.

Can a client change the URL and see somebody else's sites?

There is nothing to change. The page never reads an identifier from the address bar: the token resolves to one client record, and every read is filtered by that record's id in the SQL itself. An unknown, malformed or disabled token gets the same 404, so the link cannot be used to find out which tokens exist.

Will the client page turn up in a search engine?

It sends X-Robots-Tag: noindex, nofollow, noarchive, Referrer-Policy: no-referrer and Cache-Control: private, no-store. The referrer header matters more than the first one here: without it, every outbound click from that page would hand the token to the site being linked to, and it would land in somebody else's access log.

Is this in the free engine or only in the hosted plan?

In the engine, which is MIT licensed and the same code either way. There is no paid edition and no feature flag: if you install it yourself, client links work on the first run. The hosted plan sells the server and the upkeep, not a different program.

Send one to a client this week

Or check one of their sites right now, without an account, and see what the status code was covering for.