Skip to content
Blog

What it takes to track 900+ services honestly

A week ago the outage catalog covered 195 services. It now covers more than 900. The story is not the count, it is the rejection list behind it: what we would not add, and why.

A week ago the outage catalog tracked 195 services. It tracks more than 900 today. That is not a milestone we are announcing so much as a number that fell out of the actual work, which is curation, not counting.

Anyone can write a script that pings a thousand homepages and calls the result a status page. We do not think that is honest, and we would rather grow slowly than publish a green checkmark that means nothing. So here is what actually happens before a service earns a row in the catalog, and, more usefully, a partial list of what did not.

The bar for adding a service

Every candidate URL gets a real, unauthenticated GET from our own machine, with the published probe user agent, before it is added. Not a documentation claim, not "this should work," an actual curl. If the response is not what we expect, the candidate does not go in as-is.

That single step throws out more candidates than it lets through. Across the tranches that took the catalog from 195 past 900, entire batches of well-known names came back bot-walled and were dropped rather than added with a caveat: Netflix and Snapchat on every candidate API host, HSBC, ING, eBay, Bybit, 1Password, Chase, Bank of America, Wells Fargo, Capital One, American Express, Verizon, AT&T, Vodafone, Zalando, Deutsche Bank, Santander, and dozens more in that single pass, all rejected as bot-walled challenge pages, CDN/WAF block pages, or geo-blocks. Vultr, Equinix, Vonage, and Perplexity were dropped from a "deep endpoint" tranche because their product surface came back 403 the day we checked. Braintree was dropped outright because its old endpoint now redirects to a query-string-bearing PayPal migration page, not because the check failed but because there was no honest thing left to check. HMRC was dropped as a duplicate of the UK government's own domain rather than counted twice. Ooredoo was dropped for a flat 403.

None of those are "coming soon." They are gone from this round because we could not verify them honestly, and a catalog that counts unverifiable rows is worse than a smaller one that does not.

Why a healthy code is not enough on its own

The harder problem is the services that answer, but answer with a status code that could mean two different things. A 403 can mean "this account is not authorized" or it can mean "a bot-defense product intercepted the request before it reached the service at all." Both look identical on the status line.

For those endpoints we do not trust the code alone. We add an expect: a stated assertion about what a healthy response's body, header, or JSON shape has to look like, checked against up to 256 KB of the actual response. Mercadolibre, DeepL, Healthgrades, and Etsy all answer 403, and all four carry an expect that proves the 403 is the service's own JSON error body, not a WAF challenge page that happens to share the status code. Without that assertion, declaring a 403 "healthy" would be indistinguishable from declaring a block page healthy, which is exactly the kind of lie a bigger number should never buy.

The same discipline decides which endpoint a service gets probed on at all. A marketing homepage answering 200 mostly proves a CDN is up. Where we can find one, we prefer a real, documented API or auth surface instead: Cloudflare's own IP list endpoint over its homepage, Spotify's search API returning a declared-healthy 401 over its landing page, Gmail's OIDC discovery document over a page that only proves a server exists. The catalog schema calls this the difference between reachability and functional measurement, and every service page says honestly which one it is getting, rather than letting a marketing homepage pass as proof the product works.

And every endpoint's row states, in plain language, what "down" is even allowed to mean for that specific service; that is the down_definition field, written per endpoint rather than assumed. A homepage-only reachability check for an airline is not the same claim as a functional check against a package registry's real API, and pretending otherwise is how a catalog quietly overstates what it knows.

Blocked is not down

The vocabulary matters as much as the plumbing. When a probe gets refused or filtered, that is evidence about our own reception, not a confirmed outage. We call that state blocked, never down, and it can never open or close a public incident on its own. A service we cannot honestly measure right now is marked as such; it is not silently promoted to "operational" because the alternative reading would be worse, and it is not marked "down" because a firewall having opinions about our IP is not the same claim as a vendor's product failing.

That is also why the rejection lists above are not a failure count. They are the mechanism working. A candidate that comes back bot-walled does not get downgraded into a fuzzy "probably fine" row, it gets left out of the catalog entirely until there is an endpoint we can stand behind.

Free, no account, and the actual demo

The outage tracker is free and has no account, on purpose. It is not a lead-gen gate dressed up as a public good. It is the same fleet, the same probes, and the same honesty rules that back RealUptime Monitor and RealUptime Status, pointed at more than 900 services nobody has to sign up to see. Free forever, and also our best demo: if you trust what this page says about a vendor you do not control, that is the argument for trusting it about your own service, which you do.

Read the methodology, watch the hub

The full rules, including what we do and do not measure and why a stale reading declares itself stale instead of impersonating a fresh one, are at /outages/methodology. The live board, every service, region by region, is at /outages. Neither page will tell you a service is fine because a homepage answered. Both will tell you when we simply could not check.