Three ways to check, from least to most effort.
1. The install page
Open the site's Install tab in the app. It polls, and flips from Waiting for the first pageview to Recording visits within seconds of the first view arriving.
This is the check to use, because it confirms the whole path end to end: your page loaded the script, the script sent an event, the collector accepted it, and it was attributed to the right site.
2. The browser network tab
Load a page of your site, open DevTools, go to Network, and reload.
You are looking for two requests.
t.js — the script itself.
| Status | Meaning |
200 | Loaded. |
| (blocked / failed) | An ad blocker, or a Content Security Policy without script-src. |
404 | The src URL is wrong. Copy the tag again from the install page. |
POST /api/events — the page view.
| Status | Meaning | What to do |
202 | Accepted. This is success. The body is {"ok":true} — though DevTools will not show it: the tag sends with sendBeacon, and browsers discard a beacon's response body before the Network panel sees it. The 202 in the Status column is the confirmation. | Nothing. |
400 | The payload was rejected. Body is {"error":"invalid_payload"} or {"error":"invalid_json"}. | Almost always a custom event whose name or parameters break the rules. See Tracking custom events. |
403 | Body {"error":"site_inactive"} — the site is switched off in your account. | Re-enable it in the site's settings. |
404 | Body {"error":"unknown_site"} — the site key does not exist. | The key in the tag is wrong or the site was deleted. Copy the tag again. |
402 | Body {"error":"subscription_inactive"} — the subscription has lapsed past its grace period. | Renew from Billing. This is the one status that stops data silently: the tag is correct, the site is correct, and nothing is being recorded. Not 403, so nobody rotates a site key that was never the problem. |
413 | Body {"error":"payload_too_large"} — the request body exceeded 8 KB. | A custom event with a very large parameter set. See the limits in Tracking custom events. |
429 | Body {"error":"rate_limited"} — too many events from this site in one minute. | See Events are being dropped. |
503 / 500 | Body {"error":"temporarily_unavailable"}. | A transient problem on our side. The event is lost; the script does not retry. If it repeats rather than passing, email support with the time. |
No POST at all, but t.js loaded fine. Three usual causes, in order:
A Content Security Policy that allows
script-srcbut notconnect-src. The script loads, no error appears, and every send is blocked. See Content Security Policy.You are on
localhostwithoutdata-allow-localhost="true".This browser has the ignore flag set — see My own visits are being counted.
3. A CORS error in the console
If the console shows a CORS error on /api/events, that means the browser
could not read the response. It does not mean the event was lost.
TrueStat records the event either way. The response header is only withheld
when the page's hostname does not match your site's data-domain or its allowed
hostnames — so this is a signal that you should add the hostname to your site's
Allowed hostnames, not that you are losing data.
Subdomains of your registered domain match automatically. A completely different domain does not.
What each attribute must match
| Attribute | Must be |
data-website-id | Exactly the site key from the app: ts_ + 12–32 lowercase letters and digits. Case-sensitive. |
data-domain | Your root domain, no https://, no trailing slash, no path. www. is ignored. |
A malformed site key is rejected before any lookup happens, so a typo produces
400, not 404.
Still nothing
Work through No events are showing up. It covers the platform-specific failures — published-vs-preview, plan-gated head fields, caching plugins — that the network tab does not explain.