Privacy & GDPR
Pulse is built to answer “what brings customers?” without following anyone. This page says exactly what the script does, what is stored, and what is not. Read it against the code: it is all in the open repository.
No cookies#
The tracking script sets no cookies, uses no fingerprinting and loads nothing from third parties. By default, in the visitor's browser it writes only to the tab's session storage:
| Where | Key | What and how long |
|---|---|---|
| Session storage (this tab) | pulse_vid | The visitor id Pulse returned, used to tag checkout links. Gone when the tab closes. |
| Session storage (this tab) | pulse_src | The first source of the visit (utm_source, ?ref= or referrer host), also for checkout links. Gone when the tab closes. |
| Local storage (only if you opt out) | pulse_ignore | Set by excluding your own visits. It marks a browser to be skipped. |
Local storage (only if the site enables data-attribution) | pulse_ft | The visitor id and first source, kept for 7, 30 or 90 days so a later purchase can be attributed. Off by default. Because this is stored on the device, such a site may need consent; see longer attribution. |
Nothing here identifies a person across sites or sessions, and nothing is read back to the server except the visitor id on checkout links you chose to send.
Visitor ids#
A visitor id is a one-way hash of the site id, the IP address and the browser's User-Agent, mixed with a salt that is derived from your server's secret and changes at the start of every month. The IP address is used for the hash and then discarded.
- The id cannot be turned back into an IP address or a person without the server's secret.
- Ids cannot be linked across months, so nobody can be followed for longer than a calendar month.
- Ids are per site: the same person on two of your sites has two unrelated ids.
- The trade-off is accuracy. People behind one network with the same browser can share an id, someone who switches network counts as two, and retention reads low across a month boundary. A range that crosses the 1st (every 30- or 90-day range does) counts someone who visited in both months twice, so its visitor total runs a little high.
What is stored for each event#
One row per pageview or custom event:
| Stored | Details |
|---|---|
| When and where | Timestamp, site id, the page host, path (with a #/route hash if you use hash routing) and page title. |
| Where from | Referrer host and path, a derived channel, and the utm_source, utm_medium and utm_campaign values. Other query-string parameters are dropped before storing. |
| Who, loosely | The hashed visitor id and a session id that groups a visitor's hits until 30 minutes of quiet. |
| Place | Country, and region and city when your host or Cloudflare provides them, or a local IP database on self-hosted installs. Derived from the request, not stored as an IP. |
| Device | Browser, operating system and device class (desktop, mobile, tablet) parsed from the User-Agent, plus screen size and language. |
| Your events | The name and properties you attach to custom events. |
Never stored: IP addresses, the raw User-Agent, cookies, full URLs with their query strings, form contents, or anything typed on your pages. Known bots and crawlers are dropped before anything is saved.
Payments and buyers#
For each order from a connected provider Pulse stores the provider, time, amount (net of tax) and currency, product name, billing country, whether it was refunded, the kind (one-time, subscription, renewal), the source it was credited to, and the visitor id the checkout carried. A buyer's email is stored only as a one-way hash keyed with a secret derived from the server's secret, to count repeat customers. It is never shown and cannot be read back. Names, street addresses and card details are never stored.
Account holders#
- Your name and email, and your password as a salted hash.
- Sign-in sessions, with the IP address and browser of each session so you can recognise it.
- Provider API keys, Umami keys and webhook secrets are encrypted at rest with AES-GCM under the server's secret, and are only decrypted to talk to that provider. API keys you create for Pulse are stored as a hash.
GDPR and cookie banners#
Because Pulse sets no cookies, keeps no IP addresses and cannot follow a person across sites or months, many sites run it without a consent banner. Whether you need one depends on your country, on what else your site loads, and on how your regulator reads the rules, so check with your own advisor. This is not legal advice.
- Controller: you are the controller of your visitors' data; Pulse (or your own server, when you self-host) processes it for you.
- Where it lives: in the Postgres database of the Pulse you use. Self-hosting keeps everything on your own server.
- Export: Settings, Account, Export my data downloads a .zip with your account, sites, notes, payments and the last 90 days of events for each site. It contains no API keys or passwords.
- Erasure: Settings, Account, Delete account (you type your email to confirm) permanently erases your account, sites, connections, payments, notes, API keys, alert settings and every collected event. Deleting a single site in Settings removes just that site's events, payments, notes and connections.
- Visitors: visitor ids are anonymous and irreversible, so a request to delete “one person’s” analytics cannot be matched to a row. That is by design: there is no personal data to find.
- Subprocessors: your connected payment providers (read-only), and, if you use them, the email service that sends alerts. Source icons in the dashboard are fetched by the Pulse server from Google's favicon service (only a domain name is sent, and answers are cached for a week) and served from Pulse's own address: nobody's browser, yours or a visitor's, contacts Google.
Common issues#
- Do I need to mention Pulse in my privacy policy?
- Yes, as good practice: say you use privacy-friendly analytics that sets no cookies and stores no IP addresses. Link to this page if it helps.
- Can I delete my account and my data?
- Yes. Settings, Account has Delete account, which erases everything immediately and cannot be undone. Use Export my data first if you want a copy.
- Why do I see city and region?
- Your host or Cloudflare derives them from the IP address at request time and passes them as headers; a self-hosted install without either looks them up in a local IP Geolocation by DB-IP database. Pulse stores the place, never the IP.