Privacy & compliance

Optional enrichment is off by default. Core analytics can start immediately or wait for consent depending on the site's compliance preset; identity capture, marketing fields, replay, fingerprinting, and behavioral trackers follow the consent and compliance settings you choose for that site.

Consent model

Every event the SDK emits is gated by a consent state stored in the _cs_consent first-party cookie + local-storage slot. The consent state is a tri-state per category:

CategoryDefaultWhat it gates
analyticsgranted on opt-out presets (standard, ccpa); denied until consent is granted on opt-in presets (gdpr_strict, hipaa)pageview, click, scroll, session tracking
identitydenied until explicit grantConsent('identity')HEM / phone / customer-id / social-id capture + transmission
marketingdenied until explicit grantConsent('marketing')click IDs (gclid, fbclid, etc.), UTM capture, replay, behavioral trackers

Revoking consent clears every identity slot from storage + cookies, pauses the affected trackers, and emits a _consent_transition event so the server can scrub downstream state.

Optional Visitor Enrichment

ClickStream can run an optional visitor enrichment check for a site. This is off by default.

When a site owner turns it on from the Sites page optional enrichment card or Settings → Enrichment, the SDK loads the DataShopper (DataMoon) browser pixel directly and passes the active ClickStream visitor ID as the match key. When the processor finds a match, ClickStream receives the match tied to that visitor ID and can complete the person profile.

Use this only when your privacy notice and consent flow allow optional identity enrichment. Before enabling it, site admins must confirm that they have reviewed the applicable privacy and sub-processor disclosures. When this setting is off, ClickStream does not run the optional enrichment check.

This setting is separate from normal analytics and from server-side enrichment after a form fill or explicit identify() call. Basic pageview, click, scroll, Signals, and first-party tracking do not require optional enrichment.

Compliance presets

Set the preset at install time via data-compliance or the compliance config option:

<script
  src="https://t.example.com/sdk.js"
  data-key="cs_live_..."
  data-compliance="gdpr_strict"
  async
></script>
installClickstreamPixel({
  apiKey,
  endpoint,
  compliance: 'gdpr_strict',
});
PresetConsent modeScrub levelIdentity / fingerprint defaultEncrypted-value retention
standardopt_outstandardallowed when visitor identifies90 days, auto-purge on
gdpr_strictopt_in — denied until consentaggressivedenied until identity consent180 days, auto-purge on
ccpaopt_outstandardallowed; honors DNT + GPC90 days, auto-purge on
hipaaopt_in — denied until consentaggressivedenied90 days, auto-purge on

Retention in the table above applies to encrypted raw values stored per site (retentionDays, configurable). Separately: the Analytics Engine event stream has ~90-day platform retention, R2 export objects are removed on a 90-day cleanup cycle, and the audit log is retained 7 years.

The preset sets server-side defaults via ClientConfig.complianceProfile, which the collector uses to reject any event that carries fields the preset would have stripped — defense-in-depth against an old SDK bundle being cached on a visitor's device.

Consent sources — CMP detection + setConsent()

The SDK does not render a consent banner. On opt-in presets (gdpr_strict, hipaa) tracking is denied until consent is granted, from one of two sources:

  1. Your CMP, auto-detected. The SDK detects OneTrust, Cookiebot, and Osano, mirrors their consent decision, and subscribes to consent changes. You don't have to double-integrate.
  2. An explicit setConsent() call. Any other CMP — or your own consent UI — can bridge its decision to the SDK:
window.cs?.getConsent();        // current consent state
await window.cs?.setConsent({ analytics: true, marketing: true, thirdParty: false });
await window.cs?.setConsent({ marketing: false });

With no CMP detected and no stored consent, opt-in presets collect nothing.

What's scrubbed at which level

standard scrub

aggressive scrub

All standard rules plus:

Raw PII — encrypted at rest, reveal-gated

When a site enables raw-value capture (email pre-encrypt on the server, form fills, IP addresses), values are AES-256-GCM encrypted with a unique key per site before they hit D1. Raw plaintext is never persisted anywhere.

Reveal requires all of:

  1. Dashboard operator with decrypt:read permission.
  2. Password re-authentication within the last 5 minutes (/decrypt re-auth gate).
  3. A recorded audit row (audit_log) that captures operator id + IP + target visitor + timestamp + reason text.
  4. Rate-limit allowance (10 reveals per operator per 15-minute window).

The audit log is append-only and retained 7 years; each site's Activity tab shows recent actions, and full history is available on request through support. Reveal access is controlled by the dashboard permission model, password re-authentication, and per-site encrypted storage; ClickStream operators do not bypass those gates.

Visitor rights — DSAR / export / deletion

Every dashboard site admin can:

Use tracker.setConsent({ marketing: false }) (clears identity from the browser) + the dashboard delete action (purges server-side records) for a full visitor scrub.

Server-side compliance enforcement

The SDK already strips fields based on the compliance profile before transmission, but the collector strips them again as defense-in-depth. A cached old SDK bundle on a visitor's device can't smuggle fields past the collector — the server's ClientConfig.complianceProfile rules run on every event regardless of SDK version.

Regional considerations

Data residency

DPA + sub-processor list

A Data Processing Agreement is available on request for Growth+ tiers through legal@clickstream.com; Scale+ customers can have a DPA appended to the MSA during provisioning. Current sub-processors:

The sub-processor list is published at einstein.clickstream.com/legal/sub-processors — we update that page before onboarding any new sub-processor.

See also