API

Every public report is also JSON. There is no key to request and no account to create — if a site has published its report, its numbers are readable by anyone, in the same shape the report page itself draws from.

That is the point rather than a convenience. A number you cannot fetch and check independently is a screenshot. These two endpoints are what makes the claim on the front of this site testable.

Report data

Everything behind a published report: totals, the time series the chart is drawn from, and the source, page, country, browser, system, device and campaign breakdowns.

GET https://visits.report/r/507de85247a64071f4e5583f9ba2583b/data/?period=last24h&granularity=hourly
Parameter Values Meaning
periodlast24h · last7d · last30d · last90d · all The window. Defaults to last24h; anything unrecognised falls back to it rather than erroring.
granularityhourly · daily Bucket size for the series. Omit it and each period uses its natural one — hourly for a day, daily for everything longer.

The response is one object with these keys:

{ "totals": { "pageviews": 0, "visitors": 0, "visits": 0, ... }, "series": [ { "label": "...", "pageviews": 0, "visitors": 0 }, ... ], "sources": [ ... ], "pages": [ ... ], "countries": [ ... ], "browsers": [ ... ], "systems": [ ... ], "devices": [ ... ], "campaigns": [ ... ], "live": 0 }

Live visitors

Who is on the site right now, and where they came from. Aggregates only — never a visitor id, never a path, never anything that could single out a person.

GET https://visits.report/r/507de85247a64071f4e5583f9ba2583b/live/?minutes=5
Parameter Values Meaning
minutes1–60 How far back counts as now. Defaults to 5; values outside the range are clamped, not rejected.

This one sends Access-Control-Allow-Origin: * and caches for ten seconds, so a site can embed its own independently-counted live number in its own page — and a reader can open the report and check it against what the page claims.

{ "domain": "visits.report", "verified": true, "minutes": 5, "visitors": 0, "sources": [ ... ], "countries": [ ... ], "report_url": "https://visits.report/r/…/" }

What you can count on

  • No authentication, no key, no rate limit to sign up for. Both endpoints are plain GETs.
  • A report has to be public. If its owner has not published it, both endpoints return 404 — the same answer an unknown site gets, so the API never reveals that a private site exists.
  • Nothing identifying is served, because nothing identifying is stored. IP addresses are never written down, and visitor ids are salted daily and cannot be joined across days.
  • Yesterday and earlier are sealed into a daily hash chain you can recompute yourself. The numbers in this API are the numbers in that chain.

How to verify the chain by hand →

Made by @nadermx