Privacy & Data Handling
The Hood Web SDK is built with privacy by design.
This page explains what data the SDK stores, how it behaves with or without consent, and what developers need to configure in their Consent Management Provider (CMP).
Our goal is to keep integration simple while remaining fully compliant with GDPR and other privacy standards — without unnecessary legal complexity.
Overview
All data is stored directly in the browser using:
sessionStorage– temporary data automatically removed at the end of a browser sessionlocalStorage– persistent data such as consent preferences and technical keys that last between sessions
All SDK data is kept under a single storage key called _OPC.
This key contains a JSON object with all values used by the SDK.
Example structure:
{
"_OPC": {
"session_uid": "b4f2c1e2-91d3-4a7a-a2c1-f8a3c2d7c5",
"userConsent": { "analytics": true }
}
}
_OPC key in browser storage, rename it to avoid conflicts with the SDK.Storage Overview
- Technical storage (session ID, A/B variants, dismissals) is necessary for service operation and does not require consent.
- Processing that links data to a person (profile association via
identify, campaign attribution) runs only with explicit consent per purpose keys:analytics,marketing,push. - This page is developer guidance, not legal advice.
| Storage Type | Used For | Lifetime |
|---|---|---|
sessionStorage | Temporary session tracking | Until the tab/browser is closed |
localStorage | Persistent SDK data stored under _OPC | Up to 365 days (or until manually cleared) |
Session Data (Without Consent)
When no consent is given, the SDK will:
- create a temporary session ID (random and non-persistent),
- store it as
_OPC.session_uidinsidesessionStorage, - use it to group analytics events within the same browser session.
This ID is deleted automatically when the session ends.
It cannot identify a user and does not require consent.
Example session data:
{
"_OPC": {
"session_uid": "b4f2c1e2-91d3-4a7a-a2c1-f8a3c2d7c5"
}
}
This allows the SDK to measure simple things like page views or event counts — fully anonymous.
Persistent Data (With Consent)
If the user gives consent via your CMP, the SDK can:
- keep the consent state,
- track campaign parameters (
utm_*) and push permission data, - associate events to a server-side profile when your app calls
identify(optional).
Example flow:
Hood('consent', { analytics: true });
Hood('identify', 'user_12345');
Hood('trackEvent', 'purchase', { value: 25 });
If consent is later withdrawn, the SDK will stop using identifiable data and continue with anonymous session tracking only.
identifypayloads are never stored in the browser.- Send
identifyonly when you have consent (for example,analytics: true) and do it consistently on login/auth so events can be linked across sessions. - We generate and manage the internal profile ID server-side; your external ID is attached to that profile as an attribute.
What Data Is Stored
All data is stored under the single key _OPC.
| Subkey | Storage | Purpose | Purpose Key | Lifetime | Consent Required |
|---|---|---|---|---|---|
_OPC.session_uid | sessionStorage | Temporary anonymous session ID | technical | Until session ends | ❌ |
_OPC.userConsent | localStorage | Consent states per category | technical | Until changed | ❌ |
_OPC.utm_* | localStorage | Campaign and attribution parameters | marketing | Until overwritten | ✅ |
_OPC.psh<hash> | localStorage | Functional key used to check push permission requests per domain (not user-identifying) | technical | Until overwritten | ❌ |
_OPC.modal_*, _OPC.ab_*, _OPC.webpush_dismissals, _OPC.vt | localStorage | Technical counters and A/B testing variants | technical | Until overwritten | ❌ |
How the SDK Handles Consent
The SDK includes a simple consent interface that should be synced with your CMP.
Setting Consent
Pass consent states directly from your CMP:
Hood('consent', {
analytics: true,
marketing: true,
push: false
});
Updating Consent
If the user updates consent:
Hood('consent', newConsentState);
Clearing Data
For “right to be forgotten” or user data removal:
Hood('identify', null);
Hood('consent', { analytics: false, marketing: false, push: false });
CMP Configuration Guide
In your Consent Management Provider (CMP), define the following categories and map them to the SDK purpose keys:
| Purpose | Purpose Key | When Active | Description |
|---|---|---|---|
| Analytics | analytics | analytics: true | Tracks events tied to a user if consent is granted |
| Marketing | marketing | marketing: true | Enables UTM parameter storage and campaign attribution |
| Push Notifications | push | push: true | Enables push permission state tracking (functional, not personal) |
Best Practices
- Send consent to the SDK immediately after your CMP loads
- Linking events to a person happens server-side via
identifyand requires consent (no user IDs are stored locally) - No data passed via
identify()setUserProperties()is saved locally - Use unique key names if your app also writes to localStorage
- Keep your SDK up to date — privacy rules evolve
Quick Reference
| Use Case | Requires Consent | Storage |
|---|---|---|
| Counting sessions | ❌ | sessionStorage |
| Measuring page views | ❌ | sessionStorage |
| Linking events to a user | ✅ | server-side only (no local storage) |
| Sending push notifications | ❌ | localStorage (_OPC.psh<hash>) |
| A/B testing modals | ❌ | localStorage (_OPC.ab_*) |
| Tracking campaigns (UTM) | ✅ | localStorage (_OPC.utm_*) |
Summary
- All SDK data is stored under a single key
_OPCin browser storage. - Temporary analytics works anonymously during the session.
- Persistent data (like UTM parameters) is stored only with consent.
- Push keys (
psh<hash>) are functional domain checks — never user identifiers. - The SDK is designed to remain fully compliant and privacy-safe out of the box.
Need more technical details?
Check our Integration Guide or contact our support team.