Privacy Policy
Last updated: September 5, 2026
This Privacy Policy explains how StorePilot ("we", "us", "Platform") collects, uses, stores, and protects information when Clients use the Service, and what data the Plugin may collect about end-users on Client websites.
1. Who We Are
StorePilot is a SaaS analytics and monitoring platform. For the purposes of this Privacy Policy:
- We are the Data Processor — we process personal data on behalf of our Clients according to their instructions.
- The Client is the Data Controller — the website owner who installs our Plugin and sends data to our Platform.
- End-Users are visitors to the Client's website whose data may be collected by the Plugin.
2. Data Collected by the Platform
2.1 Account Data (Client)
When you register on the Platform, we collect:
| Data | Purpose |
|---|---|
| Email address | Account identification, notifications |
| Password (bcrypt hashed, never stored in plain text) | Authentication |
| Name (optional) | Dashboard display |
| Account creation timestamp | Internal records |
We do not store payment data directly — this is handled by our payment processor (if billing is active).
2.2 Site Configuration Data
When you add a WordPress site to the Platform, we store:
- Site name and domain
- API key (used to authenticate data from the Plugin)
- Notification settings (Slack webhook URL, Telegram token, SMTP settings — stored encrypted)
2.3 End-User Data Collected via the Plugin
The Plugin may collect the following data about visitors to the Client's website, depending on which features are activated:
| Category | Data Points | Feature |
|---|---|---|
| Technical | JavaScript errors, stack traces, error type | Error Tracking |
| Technical | Server-side error messages, severity, file/line, and — from the Node SDK — the route TEMPLATE, HTTP method and status code | Backend Error Tracking |
| Technical | For failed AJAX calls: the request's field NAMES and a 500-character sample of the response | Error Tracking |
| Behavioral | Pages visited (full URL including query string), page title, time on page, session ID | Pageview Analytics |
| Behavioral | Clicks, rage clicks, dead clicks, scroll depth, element selectors | Heatmaps |
| Behavioral | Mouse movements, clicks, scroll, page content, keyboard input* | Session Recording |
| Behavioral | Network request metadata — method, URL, status, duration (never headers or bodies) | Session Recording |
| Behavioral | Browser console output** | Session Recording (opt-in, off by default) |
| Behavioral | Canvas content — the rendered pixels of <canvas> elements, captured as up to 8 image frames per second while a canvas is being redrawn***** | Session Recording (opt-in, off by default) |
| Technical | Text passed to console.error() by the site's own scripts, with a stack trace** | Error Tracking (opt-in, off by default) |
| Identity | WordPress User ID and role (if logged in) | Error Tracking, Leads |
| Contact | Name, email, phone, city/region/country. Street address and postcode are refused — see *** | Lead Capture (WooCommerce) |
| Contact | Every named field of any contact form submitted, minus credential-shaped fields*** | Lead Capture (forms) |
| Conversation | Chat transcripts received from the Client's own chat provider (Brevo Conversations): the messages as they were typed, the visitor's name and email address as the provider reported them, and the page the chat began on. Where a message carried a file, the Platform stores the chat provider's own link to it and never a copy of the file itself; the file is shown in the dashboard by loading it from the provider. Card numbers and credential-shaped values are masked before storage; email addresses and telephone numbers inside a message are KEPT, because they are the contact detail the Client reads the transcript for and the same values already sit on the lead beside it****** | Conversations (opt-in, off by default) |
| Feedback | Answers to on-site surveys — scores, selected options and free-text answers****, with session and visitor identifiers | Surveys |
| E-commerce | Cart contents, cart total, order notes | Lead Capture |
| Network | IP address (used for geolocation; always truncated to a /24 for IPv4 or /48 for IPv6 before storage) | All features |
| Device | User agent, browser, OS, screen size, language, time zone | Visitor Analytics |
| Location | Country code (derived from IP) | Visitor Analytics |
| Image | A rendered PNG of a page. Produced either from a recorded visit, or from a copy of the page serialised in a visitor's own browser when a Client has asked for an image of that page *** | Heatmap backgrounds |
* Session Recording: all form input is masked by default — what is recorded is the length of what was typed, not the characters. Passwords are never recorded. Page text that the site itself rendered is not masked: an order confirmation showing a name and address will appear in the recording as the visitor saw it. A Client may un-mask specific fields by CSS selector, which is a deliberate choice they make per field.
*** Page images: when a Client asks for an image of one of their pages, the next few visitors of that page each send one serialised copy of it. It is masked in the browser by the same rules as Session Recording before it is sent, is never taken from a visitor who has declined tracking or whose browser sends a Global Privacy Control signal, and is deleted as soon as it has been rendered into the PNG. At most three copies are taken per page, after which the request stops.
** Console output is off by default and must be switched on per site — twice over, because these are two separate switches with two separate destinations: one puts console output inside a session recording, the other files what is passed to
console.error()as an error. When either is on, it captures whatever the Client's own scripts log — which can include API responses and cart contents — and no masking rule can reach it, because there is no element to mask.
*** Form fields. Every named field of a submitted form is stored, except that two families of field keep their NAME and have their VALUE replaced with the marker
[hidden]before anything is written — so a Client can always see which fields their form carried, and never what was typed into these ones:
- fields whose name is credential-shaped (
password,token,api_key,cvv,card_number,otp,ssn,date_of_birth,nonce,session,cookieand similar);- the street address and the postcode (
address_1,address_2,postcode, and theirbilling_/shipping_spellings). A shop needs to reach a customer, which is an email and a phone number; it does not need their door. This applies to the modelled address fields as well as to the raw form record, so the Platform holds no street address or postcode for a visitor at all.city,stateandcountryare kept — that is the same coarse geography already derived from the IP address.Values that are not refused outright still pass the automatic redaction floor described above. In a session recording, all of these fields are masked like any other input and cannot be un-masked by CSS selector.
This is a floor, not a guarantee: a sensitive field with an ordinary name is stored like any other, so a Client collecting special-category data in a form should exclude that page under Settings → Privacy → Excluded URLs.
**** Survey answers. Free-text answers pass the same automatic redaction floor as other free text — email addresses, long digit runs and credential-shaped values are replaced before storage — and the same caveat applies: it is a floor, not a guarantee. A visitor writes whatever they write; a Client asking open questions on pages where special-category data is plausible should not.
***** Canvas content is opt-in, off by default, and must be switched on per site. A canvas is rendered pixels — a signature pad, a product personaliser, a drawing tool — and no masking rule can reach into pixels, so whatever is drawn on a canvas is recorded exactly as drawn. A Client who enables it is responsible for ensuring their canvases do not display personal data, or for excluding those pages under Settings → Privacy → Excluded URLs. Pages without a canvas are unaffected.
****** Chat transcripts reach the Platform only if the Client connects a chat provider, and the direction is the reverse of every other integration on this page: the provider SENDS the transcript to the Platform on the Client's own configuration. The Platform never sends anything back to the provider and holds no credential for it. One thing does travel toward the provider, and not from the Platform: where the Client has embedded the provider's chat widget on their site, the collector hands that widget two pseudonymous identifiers —
STOREPILOT_VISITOR(the browser identifier above) andSTOREPILOT_SESSION(the visit) — inside the visitor's own browser, so that a transcript can be matched to the visit it began in. Nothing else is handed over, and it happens only where tracking is allowed: a visitor who refused consent, or who sends Global Privacy Control, is not announced to the widget at all.
3. Legal Basis for Processing
We process data on behalf of our Clients (as Data Processor). The legal basis for processing end-user data is determined by the Client (Data Controller). Typically this will be:
- Legitimate interests — for error tracking and technical analytics;
- Consent — for session recordings, which require explicit cookie/tracking consent from the visitor;
- Contract performance — for lead data submitted through checkout forms.
4. Data Retention
Retention runs automatically every night. These are the platform defaults:
| Data Type | Default Retention |
|---|---|
| Pageviews, clicks, scroll depth | 90 days |
| Session recordings (rows and video files) | 14 days, or 3 days for a visit that showed nothing, or 24 hours for a visit that produced no recording at all, or for one judged automated |
| Heatmap background images | 90 days (removed with the pages they belong to) |
| JavaScript / PHP errors | 180 days from the last time the error occurred |
| Visitor records | 400 days, and only once no pageview, lead or recording still refers to them |
| Leads | Kept indefinitely unless the Client sets a limit |
| Chat transcripts | Kept indefinitely unless the Client sets a lead limit — a chat is the same person's own words as the form beside it, and one exchange does not get two windows |
| Survey responses and answers | 365 days |
| Aggregated statistics (daily counts, heatmap grids) | 2 years |
| Uptime check history | 30 days |
| Generated export files (scheduled CSV exports) | 7 days |
| Account data | Until account deletion |
| Refresh tokens | 7 days (auto-expired and cleaned up daily) |
A scheduled export produces CSV files on the platform's own disk. Each file is a copy of personal data the tables above already hold, so it is removed after 7 days — the download link in the dashboard then reports the file as expired. Recipients of the notification mail receive a link to the dashboard, never the file itself.
A recording that showed nothing — a single page, under ten seconds, no clicks, no error and no frustration — is removed after 3 days rather than 30. This is a shorter window inside the one above, never a longer one: nothing is kept for more time than the table states. Such a visit is also hidden from the recordings list by default, with a count of how many were hidden and a control to show them.
A visit that produced no recording at all — the visitor left before the first fragment of footage could be uploaded, so the row names a page and nothing more — is removed after 24 hours. It is likewise hidden from the recordings list by default and counted separately from the visits above, because "there is nothing to watch" and "it was not worth watching" are different facts about different visits.
A visit our classifier judges to be automated traffic — a crawler, a scraper, a synthetic monitor — has its footage removed after 24 hours. The day is an appeal period rather than a delay: a first verdict is reached within the hour a visit ends and is re-checked the following night with every late signal in place, so nothing is destroyed before the check that could overturn it has run. Such visits are also hidden from the recordings list by default, counted separately, and shown by the same control that reveals the visits above. Automated traffic is reported as a statistic about the site and is excluded from the figures describing your customers.
Leads are the only category kept indefinitely by default: they are the output of the product rather than telemetry, and deleting a Client's sales pipeline on a schedule they did not choose would be the wrong default. Clients who need a limit — GDPR Art. 5(1)(e) storage limitation is the Controller's obligation — set one under Settings → Privacy → Delete leads after.
Clients may delete any data at any time through the dashboard, and the right-to-erasure endpoint removes one visitor's data outright.
5. Data Storage & Security
- The Platform database is hosted on a dedicated server with restricted access.
- All data in transit is encrypted using TLS 1.2+.
- Session recording files are stored on the Platform's own server. Where a Client asks us in writing to keep their recordings in object storage the Client themselves owns and pays for, we will configure that for their site alone; those files then live in the Client's own cloud account, under their own access controls, and no storage provider of ours is involved. Recordings made before the Platform owned storage may still reside on the Client's own server or S3 bucket.
- Notification credentials (Slack and n8n webhook URLs, Telegram bot tokens, and an email-service-provider API key such as Klaviyo) are encrypted at rest with AES-256-GCM and are never returned by the API once saved — the dashboard shows a mask, not the value.
- Access to the Platform database is restricted to production server infrastructure only — ports are not exposed to the public internet.
- Authentication uses JWT tokens with short expiry (15 minutes) and refresh token rotation.
6. Data Sharing
We do not sell, rent, or share end-user data with third parties for marketing purposes.
Data may be shared only in the following circumstances:
- With the Client — Clients have full access to data collected from their own websites.
- Nobody, for recordings — session recording files are stored by the Platform itself; no third-party storage provider of ours is involved. The one exception is at a Client's own written request: where a Client asks for their recordings to be written to object storage in their OWN cloud account, we configure their site to do that. That storage is the Client's, chosen by the Client and billed to the Client — it is their own infrastructure, not a sub-processor we have engaged, and it is never done on our initiative or for any other Client. Recordings made before the Platform owned storage may still reside on the Client's own server or S3 bucket, which we cannot reach — deleting those files is the Client's own task.
- Notification services — If the Client configures Slack, Telegram, or email notifications, event summaries are sent to those services according to the Client's settings.
- Chat providers — inbound only — Where the Client connects a chat provider (Brevo Conversations), that provider sends chat transcripts TO the Platform on the Client's configuration. Nothing travels the other way from the Platform: it never sends a message, a visitor or any other data to the provider, and holds no credential for it. The one exception runs inside the visitor's own browser, not through us: where the Client has embedded the provider's widget, the collector hands it the pseudonymous
STOREPILOT_VISITORandSTOREPILOT_SESSIONidentifiers so the transcript can be matched to the visit — only where tracking is allowed, and nothing else. - A model provider of ours — Anthropic writes the daily and weekly digest's narrative, and the summary of a recorded visit, from a statistics sheet the Platform assembles first: counts, revenue totals, page paths, error messages, uptime results and survey scores — and, where you connect a chat provider, the chat itself, so that the morning brief can say what somebody asked about; and what somebody wrote in an enquiry form on your site, shortened, so the brief can say who is waiting for an answer. Never a survey answer a visitor typed, never a visitor or session identifier, never a contact field, never an IP address, and never recording footage. Error messages and page paths are redacted before the sheet is sent, and a chat transcript, like the text of an enquiry, has email addresses, telephone numbers, card numbers and credentials masked on the way — including the visitor's name where we hold one. Of an enquiry the sheet carries whether there is an email or a telephone number to reply on, never the address or the number itself. Anthropic is a sub-processor of ours under the DPA.
- An AI client the Client connects — Where the Client connects an AI client of their own (for example Claude, through the Model Context Protocol), that client reads aggregate statistics, analytics, issues, uptime results, product performance, derived insights, checkout and order records including basket contents and totals, the names and contact details on those records, chat transcripts, survey answers including free text, and a description of a recorded visit — its pages, duration, device and error count, and the narrative summary written about it — together with the pseudonymous visitor and session identifiers that link them. Raw form contents are read only where the connecting person holds the admin role. It never receives a postal address or a postcode — those are refused at collection and a marker is stored in their place — it never receives an IP address, and it never receives session-recording footage: a visit is described and linked, never handed over. Access is read-only, limited to the sites the Client names when connecting it, and re-checked against their live team membership on every request. The Client disconnects it from Your profile → Connected AI clients → Disconnect, which takes effect immediately. The provider of that client is the Client's sub-processor, not ours.
- Legal obligations — If required by law, court order, or governmental authority.
7. Data Subject Rights (End-Users of Client Websites)
End-users of Client websites should direct privacy requests to the website owner (the Client), who is responsible for responding as Data Controller. The Platform provides tools to support:
- Right to Access and Portability —
GET /api/v1/sites/:id/visitors/:id/export.jsonreturns everything held about one visitor as a single JSON file: their visitor record, pageviews, leads, recording metadata, clicks and scroll marks, session facts, consent decisions, chat transcripts and the faults they encountered. Where the same person used more than one browser, the linked records are listed rather than merged, because a visitor identifier identifies a browser and not a person. Two limits are stated in the file itself: session replay footage is described by its metadata rather than embedded, and error entries are reduced to the fault, because the full record is an aggregate across every visitor who encountered it. - Right to Erasure — Clients can permanently delete all data for a specific visitor using
DELETE /api/v1/sites/:id/visitors/:id/data. This removes pageviews, recordings, leads, clicks, consent records, chat transcripts and rendered page images, and anonymizes linked error records. A transcript is found both by the visitor identifier and by the email addresses their leads carry, so one whose lead has already been erased still goes with them.
8. Storage Used by the Platform Dashboard
The Platform dashboard (used by Clients, not end-users) sets no cookies at all. Authentication tokens are held in localStorage:
| Key | Purpose | Duration |
|---|---|---|
access_token | Authentication JWT | 15 minutes |
refresh_token | Silent re-authentication | 7 days |
These are strictly necessary to keep you signed in and are not used for analytics or advertising.
StorePilot's collectors set one first-party cookie, sp_vid (a browser identifier, two years, renewed on each visit), and duplicate it in localStorage; visit-scoped keys live in sessionStorage. The full list is in the Cookie Policy. The Client is responsible for disclosing this in their cookie notice and, where the law requires it, for obtaining consent first — Settings → Privacy → Require consent before tracking enforces that.
Global Privacy Control is honoured unconditionally on every site, with no setting to disable that. It is honoured in the browser and again on the request: the collectors refuse to send anything when navigator.globalPrivacyControl is set, and the Platform refuses to store anything sent with a Sec-GPC: 1 header — including submissions forwarded server-side by WordPress, where no script of ours is involved. In California and the other states with universal opt-out laws, Global Privacy Control is treated as a valid opt-out request.
Do Not Track (navigator.doNotTrack, the DNT: 1 header) is not honoured. The W3C discontinued that specification in 2019 and no privacy law names it; browsers that still offer the switch describe it as advisory. Sites that want visitors asked before anything is collected can switch on the consent gate described in the Cookie Policy.
9. Changes to This Policy
We will post any changes to this Privacy Policy on this page and update the "Last updated" date. For material changes, we will send registered account holders an email notification.
10. Contact
Data Controller inquiries (Client accounts): contact@store-pilot.net
Data subject inquiries (end-users of Client websites): Contact the website owner directly.