Reading results
A check is split into cohorts: one per country, operator and connection
type. Each finished cohort has a result. This page explains its
fields. Field-by-field definitions are in the
reference.
Outcomes
Every cohort result has exactly one outcome. There are nine,
and the set is closed: no new outcomes appear within /v1. New
block methods and reasons can.
Four outcomes are verdicts about the site (verdict: true):
| Outcome | Meaning |
|---|---|
ok | The site opens: content came back and the certificate is valid for the name. |
blocked | The site is blocked. layer and method say where and how. |
target_down | The site does not work from anywhere, our control measurements included. Not a block. |
target_policy | The site itself refuses this visitor: anti-bot protection, a geofence, a rate limit. |
Five outcomes are not verdicts (verdict: false). They mean we
could not get a trustworthy answer, and they say nothing about whether the site
works. Do not show them to your users as "up" or "down".
| Outcome | Meaning |
|---|---|
provider_policy | The proxy network we measure through does not allow this site. Not censorship. |
exit_regime | The whole network is under a special regime, such as an allowlist or a shutdown. |
proxy_failure | Our measuring point failed (the exit changed or disappeared, or the proxy network failed), not the site. |
inconclusive | Too little data, or the data contradict each other. |
not_measured | Nothing to measure with here, or measuring is not allowed. Not charged. |
Every outcome except ok and blocked has a
reason, for example exit_changed for a
proxy_failure or no_vantage for a
not_measured. The reference lists every reason.
Layers and methods of a block
For blocked, read layer and method
together, as in dns.redirect. Some common ones:
| Layer.method | What happens |
|---|---|
dns.redirect | The operator's DNS points the name to its block page. |
dns.nxdomain | The operator's DNS says the name does not exist, and that answer is forged. |
tls_sni.reset | The connection is reset when the TLS handshake names the site. |
ip.drop | Traffic to the site's IP address is dropped. |
http.blockpage | An HTTP block page comes back instead of the site. |
tls_mitm.substitution | A certificate from an issuer that is not publicly trusted replaces the site's. |
Both lists can grow within /v1. If you meet a value you do not
know, show it as it is rather than failing.
Confidence and uncalibrated
Verdicts carry a confidence label. It is a label, never a
probability:
confirmed: direct evidence (for example the operator's block page) and enough independent subscribers and subnets.likely: enough subscribers and subnets, and clean control measurements, but no direct evidence.partial: exits in this cohort disagree and no condition explains it.conditions.sharegives the share that saw the block.insufficient: not enough subscribers and subnets.
uncalibrated: true means the thresholds behind these labels
have not been calibrated against real data yet. While it is set, results show
no percentages, and a verdict without direct evidence is at most
likely. Until calibration is done, results carry uncalibrated: true
and versions.calibration: "none".
Coverage and the yellow ok
coverage.checked and coverage.unchecked list the
layers that were and were not measured (dns, ip,
tcp, tls, http, content,
quic, ech). A layer we did not check is never counted
as fine.
coverage_gaps lists the country's main layers that were not
checked. An ok with a non-empty coverage_gaps is a
"yellow" ok: the site opened, but part of the picture is missing.
For example, "coverage_gaps": ["dns"] means the site loaded through
the operator's network, but we could not observe the operator's DNS answer.
In countries where blocks are done in DNS, that matters, so tell your users the
ok is incomplete.
Evidence and explanation
evidence says what the result rests on: how many independent
subscribers, subnets and pools of exits were used, and how many measurements
were left out and why (excluded). measurement_ids
point to the measurements; GET /v1/measurements/{id} returns
their steps and timings.
explanation.text is a short summary built from the facts of the
measurements. explanation.against lists the facts that speak
against the conclusion, if any. Set Accept-Language: ru to get the
explanation in Russian; everything else is in English.
Populations
Subscribers of one operator do not always see the same thing. When groups
differ, populations shows each group separately instead of
averaging them:
isp_default: subscribers who use the operator's own DNS resolver, which is the default.public:<service>: subscribers who use a public DNS resolver, for examplepublic:cloudflare.optin:<filter>: subscribers with an operator filter that each customer can switch on or off, for exampleoptin:telenor_nettvern. This group never decides the cohort's outcome.this_exit: what one particular exit saw.
For example, a site blocked in Telekom's DNS but reachable for subscribers who use Cloudflare DNS:
"outcome": "blocked",
"layer": "dns",
"method": "redirect",
"populations": [
{"group": "isp_default", "outcome": "blocked", "layer": "dns", "method": "redirect"},
{"group": "public:cloudflare", "outcome": "ok"}
],
"conditions": {"groups": ["isp_default"]}
populations is empty when all groups see the same.
conditions says under which conditions a block shows when it does
not show everywhere: only on IPv4 (family), only for some groups,
only in a time window, or only for a share of the measured subscribers.
Registry status
If the name is in a known national block registry, the result has
registry with its status (listed,
pending, delisted, not_listed,
non_public, unknown_stale), the source and dates.
This is kept apart from the outcome: a name can be listed and still open,
for example while operators still have time to apply the order.
Filters outside the operator: user_filters
A site can also be blocked by something the visitor uses on top of their
operator: a filtering public DNS, an ad blocker, a browser warning. These checks
are the same for every operator, so they sit in one list on the check,
user_filters, and never change a cohort's outcome.
Each entry has a kind, service, mode,
verdict, observed_from (where it was seen) and
checked_at:
public_dns: public filtering resolvers such as Cloudflare 1.1.1.3 (family), Quad9, DNS4EU, CleanBrowsing, AdGuard and OpenDNS, asked from our server in the country.signalshows the sign of the block, for example0.0.0.0orEDE 17. A service that did not answer has no entry.browser_reputation: Google Safe Browsing (the lists Chrome, Firefox and Safari warn on), how Chrome shows a look-alike name, and whether Chrome removes the site's ads.threat_typesnames the lists that matched;explanationsays what visitors see.
Verdicts here are blocked (a red warning page instead of the
site), warning (a warning the visitor can click through),
partial (the site opens without some parts, such as ads),
notice, ok, not_loaded and
not_checked.
Real browsers
Add browser to the request to open the URL in real, current
Chrome and Edge, the way a visitor would:
{
"url": "https://example.org/",
"targets": [{"country": "DE"}],
"browser": {"browsers": ["chrome", "edge"], "country": "DE"}
}
Each browser adds one user_filters entry with
kind: "browser_reputation", service: "chrome" or
"edge", observed_from: "browser_worker" and a
browser object: the browser version, which warning page it showed
(interstitial, none if none), the final URL, load time,
how old its warning lists were, and screenshot_url. Fetch the
screenshot (a JPEG) with the same key; screenshots are kept for 30 days.
With country, the page loads through a home connection in that
country, so the site answers as it does to visitors there. Without it, the
browsers open it from our server in Germany. The browsers' own warning lookups
are the same everywhere.
Linux browsers do not show download warnings or Chrome's "Did you mean …?" page for names in look-alike letters, so those are never reported. Test keys do not open browsers.
Versions
Each cohort result has versions: the engine, the decision
rules, the calibration and the country's geo pack, with the pack's status. If
two results have different versions, they may have been produced by different
rules.
geo_pack_status: "shadow" means the country's rules are still
being validated on real data. Results are shown, but they may be incomplete
and may change once the pack reaches production.