Privacy tiers
Pipetrace records every visit at one of three tiers. The site's privacy settings and the visitor's own choices decide which one, and every dashboard number shows which tier it came from.
Nothing recorded at tier 1 or tier 2 is linked to a tier 3 visitor. When a visitor accepts on the same page, that page's tier 1 or tier 2 page view is deleted and replaced by its tier 3 page view. Nothing is copied from it; for a tier 2 page view, the server only checks whether its session has other page views, to decide whether the tier 3 page view continues a visit.
The three tiers
| Tier | When | Browser storage | Identifiers |
|---|---|---|---|
| 1: Anonymous counts | Before the visitor chooses, and after a refusal. This is the default for new sites. | None | None: no visitor or session ID. |
| 2: Anonymous sessions | Before the visitor chooses, and after a refusal, if the site owner turns it on. | None | A daily visitor code computed on the server, pseudonymous within a UTC day, and a random session ID. |
| 3: Consented analytics | After the visitor accepts, or where the site's settings do not ask first. | Tier 3 stores a random visitor ID in the first-party cookie _pt_vid, which expires 730 days (about 2 years) after it was last set (the tracker sets it again on every tier 3 page load), and in localStorage and IndexedDB, which have no expiry; it keeps a per-tab session ID in sessionStorage. | A random visitor ID and a session ID. |
What tier 1 keeps
At tiers 1 and 2, the tracker stores nothing in the visitor's browser. It reads one thing, and only before switching to tier 3: an opt-out saved in localStorage (_pt_consent) by the older optOut() call. If it finds one and the visitor has not accepted, it stays at tier 1. It sends page views, and custom events and goals by name only. The server keeps these fields:
- The event type: page view, custom event or goal
- Event data with at most three keys: page_instance_id, a random ID for the page load, shared by the events sent from that page and used to replace this page view if the visitor accepts on the same page; contract_version, the tracker's event format version; and, for custom events and goals only, name, the event's name. Never properties, values or revenue
- A random ID for the event, used to drop duplicate deliveries
- The time the server received it, truncated to the minute
- The page path; a fragment that could carry a token is removed
- The page URL with only the UTM campaign parameters kept
- The referring site's origin (not the full address), and its source and medium
- UTM campaign tags
- The country, looked up from the request
- Device type and browser family, from the user agent
- The primary language (for example “pt”), from the Accept-Language header
- Whether the page view started a visit: a full page load with no referrer or from another site, not a reload or back/forward navigation
Page URLs keep only these query parameters: utm_source, utm_medium, utm_campaign, utm_term, utm_content, utm_id. Custom-event and goal names are kept only if they are at most 64 characters of lower-case letters, digits and _ . : -, and properties, values and revenue are never kept.
The visitor ID and session ID are always empty. The IP address is used to look up the country and, briefly, to protect the service from abuse. Pipetrace does not store it: no event or other database record contains it, and the Pipetrace API leaves it out of its request logs for the tracking endpoints, the policy lookup and the tracker script. Time on page, scrolling, performance, errors and forms are not recorded.
What tier 2 adds
Tier 2 keeps the tier 1 fields and groups page views into visits. Its visitor code is pseudonymous within a UTC day: it links one visitor's page views on the same UTC day, it is never stored in the browser, and it cannot be recomputed once that day's secret key is deleted. Tier 2 adds:
- A daily visitor code: “a2_” and the first 30 hex characters of an HMAC-SHA256 of the IP address and user agent, keyed with the site's secret key for that UTC day
- A random session ID, not derived from the visitor
- The page's number within the session, and the session's first page
- Whether this is the daily code's first session that UTC day
The time is kept exactly instead of to the minute, so pages can be put in order. A session ends after 30 minutes without a page view, custom event or goal, and at midnight UTC, when the daily code changes.
The daily secret key
Each site gets a new random secret key for every UTC day. A day's key is kept until 01:00 UTC the next day, so requests still in flight at midnight resolve. A cleanup that runs every 15 minutes then deletes it, together with that day's open-session records. After that, the day's codes cannot be recomputed from the live database. The same key also protects the same-day recovery hash of consented analytics. Operator-held database backups follow their own retention.
Limits
- People who share an IP address and an identical user agent (the same browser, version and operating system, for example in one office) count as one visitor. So does everyone with the same user agent behind a proxy that does not pass on the visitor's IP address.
- A visitor whose IP address changes (a mobile network switch, IPv6 privacy addresses, iCloud Private Relay or a VPN) becomes a new visitor with a new session.
- A session that crosses midnight UTC counts as two visits, and the same person on two days counts as two visitors.
- No time on page, scrolling, bounce, performance, errors or forms.
What tier 3 keeps
Tier 3 is Pipetrace's full analytics: the fields in the data collection reference, visitor profiles, journeys and engagement.
Tier 3 stores a random visitor ID in the first-party cookie _pt_vid, which expires 730 days (about 2 years) after it was last set (the tracker sets it again on every tier 3 page load), and in localStorage and IndexedDB, which have no expiry; it keeps a per-tab session ID in sessionStorage. If that storage is empty, the server can recognise a visitor seen earlier on the same UTC day from a hash of the IP address and user agent, keyed with that day's secret key. This recovery never happens for a visitor who refused on the same page.
Consent modes
The site owner chooses one in Settings → Privacy.
| Mode | What it does |
|---|---|
| Consent required everywhere | Tier 3 starts only after the visitor accepts, wherever the visitor is. Owners established in the places on the jurisdiction page can only use this mode. |
| Consent required in consent regions | Visitors in the consent regions, and visitors whose country is unknown, must accept first. Other visitors get tier 3 without being asked, and the site owner is responsible for the legal basis there. |
| Legacy | The behaviour of sites that have never saved privacy settings. Pipetrace does not enforce consent: a script tag without data-consent, or with data-consent="granted", records tier 3, and data-consent="pending" or "denied" records tier 1. |
New sites created in the dashboard start with consent required everywhere and Anonymous counts. A saved policy applies to tracking within 5 minutes.
Before consent and after a refusal
The pre-consent setting decides what is recorded before the visitor chooses. It also applies to visitors who click Reject.
- Off: nothing is recorded. The tracker may still contact the server on each page, and the server stores nothing from those requests.
- Anonymous counts: tier 1.
- Anonymous sessions: tier 2.
With consent required in consent regions, the tracker starts tier 3 without asking for visitors outside those regions. If such a visitor refuses, the tracker stops using cookies and identifiers, and their page views are stored as Anonymous counts, whatever the pre-consent setting, including Off. Pipetrace does not remember the visitor's choice. Your consent tool must store it and load the script with data-consent="denied" on every later page; otherwise, in regional mode, a visitor outside the consent regions who refused gets tier 3 again on the next page, and so does a visitor on a legacy site.
Who gets which tier
The most Pipetrace stores for a visitor, computed on the server for every request:
| Site settings | Visitor (as your site reports it) | Most Pipetrace stores |
|---|---|---|
| Any settings | Browser sends Global Privacy Control, whether or not the visitor accepted | Nothing |
| Consent required everywhere, Anonymous counts | Has not chosen yet, or clicked Reject | Anonymous counts |
| Consent required everywhere, Anonymous sessions | Has not chosen yet, or clicked Reject | Anonymous sessions |
| Consent required everywhere, Off | Has not chosen yet, or clicked Reject | Nothing |
| Consent required everywhere, any pre-consent setting | Accepted | Consented analytics |
| Consent required everywhere, Anonymous counts | Accepted, browser sends Do Not Track | Anonymous counts |
| Consent required everywhere, Off | Has not chosen yet, browser sends Do Not Track | Nothing |
| Consent required in consent regions (owner in the United States), Anonymous counts | In Brazil, has not chosen yet or clicked Reject | Anonymous counts |
| Consent required in consent regions (owner in the United States), Off | Country unknown, has not chosen yet | Nothing |
| Consent required in consent regions (owner in the United States), Off | In the United States, has not chosen yet | Consented analytics |
| Consent required in consent regions, owner in Portugal (treated as consent required everywhere), Anonymous counts | In the United States, has not chosen yet | Anonymous counts |
| Legacy (privacy settings never saved) | No data-consent on the script tag, or accepted | Consented analytics |
| Legacy (privacy settings never saved) | data-consent is pending or denied | Anonymous counts |
| Legacy (privacy settings never saved) | No data-consent on the script tag, browser sends Do Not Track | Anonymous counts |
The server never stores more than this for the consent state your site reports (data-consent or pipetrace.consent). Pipetrace cannot check that a visitor really accepted: your consent tool is responsible for that. Events above this tier are downgraded, not rejected.
Global Privacy Control and Do Not Track
- Global Privacy Control: the tracker sends nothing, and the server stores nothing from a request that carries Sec-GPC: 1, at every tier. A later consent on that page does not change this.
- Do Not Track: Pipetrace does not keep cookies or identifiers for that visitor (if the browser sends the Do Not Track header without exposing it to scripts, identifiers created on a page are deleted as soon as the server reports it) and stores at most Anonymous counts, even after the visitor accepts. With Do Not Track and the pre-consent setting Off, nothing is stored before the visitor accepts if the visitor must be asked first (consent required everywhere, or a visitor in a consent region). A Do Not Track visitor who is not asked first (outside the consent regions in regional mode, or on a legacy site) is stored as Anonymous counts.
How the tracker learns its tier
Without data-consent on the script tag, the tracker asks GET /api/v1/policy before it touches any storage. The answer's maxTier is the most it may send. When maxTier is 0, stop says why: "gpc" (never lifted) or "policy" (the site records nothing before consent; pipetrace.consent("granted") still starts tier 3 on the same page, except for a Do Not Track visitor). cap set to "dnt" says that Do Not Track lowered the tier: the tracker then stays in minimal mode on that page, even after the visitor accepts. See the API endpoints.
Consent on the same page
When the visitor accepts, the tracker switches to tier 3 on the same page and sends a tier 3 page view. The server deletes the tier 1 or tier 2 page view it recorded for that page, so the page is not counted twice, and copies nothing from it. A visit already counted before consent does not get counted again.
The consented session starts on the page where the visitor accepted: its source is that page's own campaign tags and referrer. The original landing source stays only in tier 1 or tier 2, because linking the two would join the tiers.
Retention
Each site keeps its data for 1 to 25 months (25 months unless the owner changes it). A job that runs every 6 hours deletes older events, hourly statistics, and visitor aliases and archetype memberships whose visitor has no remaining events. Lowering the retention deletes older data at the next run. Daily secret keys are deleted much sooner (see The daily secret key). Operator-held database backups follow their own retention.