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

TierWhenBrowser storageIdentifiers
1: Anonymous countsBefore the visitor chooses, and after a refusal. This is the default for new sites.NoneNone: no visitor or session ID.
2: Anonymous sessionsBefore the visitor chooses, and after a refusal, if the site owner turns it on.NoneA daily visitor code computed on the server, pseudonymous within a UTC day, and a random session ID.
3: Consented analyticsAfter 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.

Who gets which tier

The most Pipetrace stores for a visitor, computed on the server for every request:

Site settingsVisitor (as your site reports it)Most Pipetrace stores
Any settingsBrowser sends Global Privacy Control, whether or not the visitor acceptedNothing
Consent required everywhere, Anonymous countsHas not chosen yet, or clicked RejectAnonymous counts
Consent required everywhere, Anonymous sessionsHas not chosen yet, or clicked RejectAnonymous sessions
Consent required everywhere, OffHas not chosen yet, or clicked RejectNothing
Consent required everywhere, any pre-consent settingAcceptedConsented analytics
Consent required everywhere, Anonymous countsAccepted, browser sends Do Not TrackAnonymous counts
Consent required everywhere, OffHas not chosen yet, browser sends Do Not TrackNothing
Consent required in consent regions (owner in the United States), Anonymous countsIn Brazil, has not chosen yet or clicked RejectAnonymous counts
Consent required in consent regions (owner in the United States), OffCountry unknown, has not chosen yetNothing
Consent required in consent regions (owner in the United States), OffIn the United States, has not chosen yetConsented analytics
Consent required in consent regions, owner in Portugal (treated as consent required everywhere), Anonymous countsIn the United States, has not chosen yetAnonymous counts
Legacy (privacy settings never saved)No data-consent on the script tag, or acceptedConsented analytics
Legacy (privacy settings never saved)data-consent is pending or deniedAnonymous counts
Legacy (privacy settings never saved)No data-consent on the script tag, browser sends Do Not TrackAnonymous 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.

Related pages