What GrainQL stores
GrainQL sets no cookies. Until a visitor grants consent, it identifies the visitor with an ID that rotates every day. The data GrainQL collects depends on the consent state:
The GrainQL Tag keeps a few values in the
localStorage of the browser, under keys that start
with _grain_<tenant-alias>_. None of them is a cookie.
GrainQL strips query parameters from the page path before consent. A query string can carry
personal data. Every event carries a
_consent_status property with the value granted or
pending, so the dashboard can separate the two states.
Consent also gates the automatic properties, for example the referrer, the page title, and the
UTM parameters. Read Automatic tracking. Read
Automatic properties.
Consent modes
Each SDK has aconsentMode configuration value. The default mode of both SDKs needs no consent
banner. The TypeScript types of the published packages win over this page when they disagree.
GrainQL Tag
The instance exposes three consent calls:
The categories are
necessary, analytics, functional, and marketing.
Analytics Web
The
waitForConsent configuration value applies to GDPR_STRICT only. When it is true, the
SDK holds events in a queue until the user grants consent, then sends them.
onConsentChange(listener) and offConsentChange(listener) subscribe to changes of the state.
The SDK stores the consent preference itself in localStorage. This storage holds the
preference only, not a tracking identifier.
IP addresses and location
GrainQL reads the country, the region, the city, and the time zone from the request. It does not store the IP address with the event.Remove query strings
Turn on Remove query strings in Settings, then Privacy and data, to drop everything after? from every page URL. An email address or a token in a link then never reaches GrainQL.
Data history and retention
Your plan sets the data history: how far back the dashboard, Neo, and the Query API read your events. Read Plans and limits.
The Retention policy of the workspace follows the plan by default. An admin can set a shorter
or a longer period in Settings, then Privacy and data.
You can export the data of a user before the retention period ends. Read the next section.
User rights
The privacy endpoints take the tenant alias in the path and the API key in theX-API-Key
header. Read Authentication.
Access (GDPR Article 15)
The export returns JSON with every event, every property, and the consent history of the user.Erasure (GDPR Article 17)
Anonymization
Anonymization replaces the user ID with a random UUID. The aggregated analytics stay intact.Data residency
GrainQL stores and backs up analytics data in ISO 27001 certified data centers of Hetzner in Helsinki, Finland. Cybentis Oy, the company behind GrainQL, is a Finnish company.Processors
The full list of the services that process data for GrainQL, with the purpose, the data, and the location of each, is at grainql.com/privacy. The privacy page, the privacy policy, and the security page show the same list. This page does not copy it. The main groups are:GrainQL gives 30 days of notice before it adds a subprocessor.
Certifications
GrainQL does not hold its own SOC 2 or ISO 27001 certificate. The data centers that store the analytics data are ISO 27001 certified. The data processing agreement covers GDPR processing and includes the EU Standard Contractual Clauses.Security measures
Incident response
Dashboard privacy controls
The privacy settings are in Settings, then Privacy and data, athttps://grainql.com/dashboard/settings/privacy:
Read Install GrainQL for the code that installs the SDK and the consent calls.