Skip to content

CanaryLytics

Cookieless web analytics. No cookies, no fingerprinting, no raw IPs, and the API key is the whole account.

CanaryLytics is a cookieless web analytics product built around one idea: the API key is the account. There is no email/password signup. A single secret key (cly_live_<32 hex>) logs you into the dashboard, authorizes SDK and REST reads, and authorizes the embeddable widget. It is locked to the domains you register, so it can be rotated at any time and never needs to appear in a page’s source.

The public tracking snippet carries no key at all. It reports the domain it runs on; the ingest endpoint resolves your project from that domain and checks the request’s Origin header against your trusted-domain list before accepting anything.

No key on the page

The snippet is keyless. Nothing secret ever ships in your page source, so there’s nothing to steal from view-source.

Cookieless by design

Sessions live in tab-scoped sessionStorage. No cookies, no cross-site identifiers, no consent banners required.

Silent by default

/ingest always answers 204. A misconfigured snippet fails quietly instead of leaking information about your setup to strangers.

One script tag. No key, no config file, no build step:

<script src="https://cdn.analytics.canarycoders.es/lytics.js" data-domain="myapp.com" defer></script>

Pageviews, SPA navigations, link clicks, sessions, traffic sources, and UTM campaigns are tracked automatically. The quickstart takes you from zero to live data in under five minutes.

Every event CanaryLytics stores is scoped to a single browser tab’s session. There is no cross-site identifier, no persistent cookie and no device fingerprinting. A visitor who closes the tab and comes back later is a new, unlinked session, and that is deliberate. Cross-origin referrers contribute only their hostname (never path or query), so search terms and personal URLs never leave the visitor’s browser.

Raw IP addresses are never written to the database. What gets stored is the coarse geo Cloudflare’s edge has already resolved: country, region, city, ASN. There is no fingerprint and no user id, so nothing links a visitor across sessions, devices or sites.

Bots and datacenter traffic are labelled rather than dropped. You can filter them out of any report, but the underlying events stay, so the numbers never quietly disagree with your server logs. Referrers get classified into a traffic-source label (search, social, direct, referral) and the raw referrer is then discarded.

Section titled “Do I need a cookie consent banner to use CanaryLytics?”

No. CanaryLytics sets no cookies and stores no cross-site identifiers. Sessions live in tab-scoped sessionStorage and end when the tab closes, so there is nothing for a consent banner to disclose.

What data does CanaryLytics store about a visitor?

Section titled “What data does CanaryLytics store about a visitor?”

Coarse geolocation from Cloudflare’s edge (country, region, city, ASN), coarse browser, OS, and device-type buckets, a truncated user agent, a traffic-source label, and a random tab-scoped session id. Never a raw IP address, fingerprint, or user id. See what gets stored for the full breakdown.

Can someone steal my analytics key from my page source?

Section titled “Can someone steal my analytics key from my page source?”

No. The tracking snippet carries no key at all, because ingest resolves your project from the domain it reports. The only key that belongs in public HTML is the read-only key (cly_read_…), which can read stats but can never change settings or write events.

Does the tracking snippet slow my site down?

Section titled “Does the tracking snippet slow my site down?”

No. lytics.js is ~2.5 KB min+gzip with zero dependencies (the size budget is enforced by the build), loads with defer, and sends events with fetch keepalive, so it never blocks rendering or navigation.

Does CanaryLytics work with single-page apps?

Section titled “Does CanaryLytics work with single-page apps?”

Yes, automatically. The snippet patches history.pushState/replaceState and listens for popstate, so client-side route changes fire pageviews with no extra configuration. Hash-based routers opt in with data-hash.

Every page of this documentation is available as plain markdown, following the llms.txt convention:

The same files are mirrored at the site root (/llms.txt, /llms-full.txt, /llms-small.txt) for automatic discovery.