The complete list. If a field is not here, it is not stored.
What is recorded for each page view
| Field | Where it comes from | Example |
| Path | The page's path only — no origin, no query string | /pricing |
| Referrer | The Referer header, if any | https://news.ycombinator.com/ |
| Event type | view, goal, scroll, link_click | view |
| Session identifier | Derived — see How visitors are counted | 4f2a… (32 hex characters) |
| Country / region / city | Derived from the IP, which is then discarded | Germany / Berlin / Berlin |
| Browser | Parsed from the user agent | Firefox |
| Operating system | Parsed from the user agent | macOS |
| Device type | Parsed from the user agent | desktop |
| User agent | The raw string, capped at 512 characters | |
| Is it a crawler, which one, and why | Classified from the user agent on our servers | true / claude / ai_training |
| Your custom parameters | Only what you send | { "plan": "growth" } |
| Timestamp |
That is the whole row.
What is never stored
The visitor's IP address. It arrives with the request, is used to derive a country, a region, a city and — on the cookieless modes — a session identifier, and is then gone. It is never written to a column, a log line, an error message or a metric label. There is no function anywhere in the product that returns, formats or echoes an IP address.
No name, email address, account id or any other personal identifier, unless
you send one yourself in a custom event parameter. Please do not — the parameters
you attach to a goal are stored verbatim, so an event named signup carrying
email: "someone@example.com" puts that address in our database, and nothing
stops you. Send an opaque reference you can resolve on your own side instead.
No form contents, no keystrokes, no clipboard, no scroll recording, no session replay, no heatmaps. None of that machinery exists. The script reads the URL, the referrer, and the attributes you put on elements.
No fingerprint. Nothing beyond the user agent and — on the cookieless modes — the IP is used to identify anyone. No canvas rendering, no font enumeration, no screen dimensions, no audio context, no WebGL, no timezone probing.
No third parties. The script talks to our collector and nothing else. No ad network, no data broker, no tag manager of ours, no analytics-on-analytics.
No query strings. The path is stored without the query string, so a
?token= or ?email= in one of your own URLs does not end up in our database.
UTM parameters are read for attribution and stored as named campaign fields
rather than as the raw URL.
The one cookie, on the default mode
On the default identity mode, the script writes one cookie:
| Name | ts_vid |
| Set on | Your domain, by the script running on your page |
| Contains | A random UUID. Nothing else. |
| Read by | The script, to attach to each event |
The cookie's value is not what we store. It is hashed together with your site's internal id first, so the stored identifier is opaque, and the same browser visiting two different customers' sites produces two unrelated identifiers. There is no way to go from what we store back to the cookie.
We cannot set this cookie ourselves — a cookie set from our domain would be a third-party cookie, which modern browsers block or partition. So it is set by the script on your domain, which is also what makes it first-party.
The two cookieless modes set nothing. No cookie, no localStorage, no
sessionStorage, no IndexedDB, nothing on the device at all. See
Identity and cookieless mode.
There is one exception on every mode: localStorage.truestat_ignore, which only
exists if you set it yourself to exclude your own browser. The script never
writes it.
What we deliberately cannot do
These are not features that have not been built yet. They are things the product is arranged to make impossible, and they are worth knowing about because several of them are standard elsewhere.
There is no way to look up an individual visitor. No visitor list, no visitor profile, no journey view, no "show me everything this person did". The identifier is a hash with no lookup table behind it, and there is nothing to attach a name to.
There is no live map of who is on the site right now. The live view is an aggregate over the last 30 minutes.
We cannot link a visitor across two customers' sites. The site id is inside every identifier, so the same person on two sites yields two values with no computable relationship.
On the cookieless modes, we cannot re-identify anyone after the fact. The daily secret used to derive identifiers is deleted when it rotates. Once it is gone, nobody — including us, with full database access — can determine who a session was, because the input no longer exists anywhere.
There is no identify() call. If you migrate from a tool that has one, the
call is accepted silently and does nothing. There is no profile for it to attach
to.
What your custom events can put in
Everything above describes what TrueStat collects on its own. Custom event parameters are the one place you can add data, and they are stored exactly as sent.
Your responsibility, not ours: do not put personal data in them. Limits and guidance in Tracking custom events.
Retention
Rows are kept for your tier's retention window and then deleted:
| Tier | Retention |
| Starter | 3 years |
| Pro | 5 years |
See Data retention.