Consent events and GDPR
Snowplow provides out-of-the-box events and entities to track user consent preferences and GDPR compliance. Use these to capture consent decisions, track changes to user preferences, and monitor Consent Management Platform (CMP) performance.
You can also configure your tracker not to track certain identifiers, depending on user consent, using anonymous tracking.
Consent API versions
Snowplow provides two versions of consent tracking APIs:
- Enhanced consent APIs: available for web only using the Enhanced Consent plugin, these APIs track detailed consent preferences and CMP visibility events
- Basic consent APIs: available for mobile, these APIs track basic consent activity
To process raw events created by the Snowplow Enhanced Consent plugin, use the consent module in the Snowplow Unified Digital dbt package.
The Snowplow dbt packages don't support the basic consent events and entities. You can however build your own models based on the raw events.
Tracker support
This table shows the support for consent tracking across the main client-side Snowplow tracker SDKs. The server-side trackers don't include consent tracking APIs.
Older versions of the web trackers provided the browser-plugin-consent plugin for basic consent tracking. It was deprecated in version 4 in favor of browser-plugin-enhanced-consent.
| Tracker | Supported | Since version | Auto-tracking | Notes |
|---|---|---|---|---|
| Web | ✅ | 3.0.0 - 4.0.0 (basic), 3.8.0 (enhanced) | ✅/❌ | Track enhanced consent events manually; configure automatic addition of GDPR entity |
| iOS | ✅ | 1.0.0 | ✅/❌ | Track basic consent events manually; configure automatic addition of GDPR entity |
| Android | ✅ | 1.0.0 | ✅/❌ | Track basic consent events manually; configure automatic addition of GDPR entity |
| React Native | ✅ | 1.0.0 | ❌ | Basic API*; no GDPR entity |
| Flutter | ✅ | 0.1.0 | ❌ | Basic API |
| Roku | ❌ | Track custom events using the enhanced schemas | ||
| Google Tag Manager | ✅ | v3 | ❌ | Enhanced consent events |
*It's also possible to use the JavaScript Enhanced Consent plugin with the React Native tracker.
Events and entities
This section describes the events and entities used in Snowplow consent tracking.
Enhanced
The Enhanced Consent plugin includes a number of tracking calls for different user consent actions:
| API | To track |
|---|---|
trackConsentAllow | Acceptance of user consent |
trackConsentSelected | A specific selection of consented scopes |
trackConsentPending | The unconfirmed selection about user consent |
trackConsentImplicit | The implicit consent on user consent preferences |
trackConsentDeny | A denial of user consent |
trackConsentExpired | The expiration of a consent selection |
trackConsentWithdrawn | The withdrawal of user consent |
trackCmpVisible | The render time of a consent management platform banner |
With the exception of the CMP visible event, these methods use the same consent_preferences event schema. The CMP visible event uses the cmp_visible schema.
consent_preferences
EventExample
{
"basisForProcessing": "consent",
"consentVersion": "1",
"consentScopes": [
"necessary",
"preferences",
"statistics"
],
"domainsApplied": [
"https://www.example.com/"
],
"consentUrl": "https://www.example.com/",
"eventType": "allow_selected",
"gdprApplies": false
}
Properties and schema
- Table
- JSON schema
| Property | Description |
|---|---|
eventType | Required. The action for the consent preferences of a user. Must be one of: deny_all, allow_all, allow_selected, pending, implicit_consent, withdrawn, expired |
basisForProcessing | Required. GDPR lawful basis for data collection & processing. Must be one of: consent, contract, legal_obligation, vital_interests, public_task, legitimate_interests |
consentUrlstring | Required. URI of the privacy policy related document. |
consentVersionstring | Required. Version of the privacy policy related document. |
consentScopesarray | Required. The scopes allowed after the user finalized his selection of consent preferences. E.g ['analytics', 'functional', 'advertisement']. |
domainsAppliedarray | Required. The domains for which this consent allows these preferences to persist to. |
gdprAppliesboolean | Optional. Determine if GDPR applies based on the user's geo-location. |
{
"$schema": "http://iglucentral.com/schemas/com.snowplowanalytics.self-desc/schema/jsonschema/1-0-0#",
"description": "Schema for consent preferences selection event",
"self": {
"vendor": "com.snowplowanalytics.snowplow",
"name": "consent_preferences",
"format": "jsonschema",
"version": "1-0-0"
},
"type": "object",
"properties": {
"eventType": {
"enum": [
"deny_all",
"allow_all",
"allow_selected",
"pending",
"implicit_consent",
"withdrawn",
"expired"
],
"description": "The action for the consent preferences of a user."
},
"basisForProcessing": {
"enum": [
"consent",
"contract",
"legal_obligation",
"vital_interests",
"public_task",
"legitimate_interests"
],
"description": "GDPR lawful basis for data collection & processing."
},
"consentUrl": {
"type": "string",
"format": "uri",
"description": "URI of the privacy policy related document."
},
"consentVersion": {
"type": "string",
"maxLength": 16,
"description": "Version of the privacy policy related document."
},
"consentScopes": {
"type": "array",
"items": {
"type": "string",
"description": "Each consent scope which has been accepted.",
"maxLength": 1024
},
"minItems": 1,
"description": "The scopes allowed after the user finalized his selection of consent preferences. E.g ['analytics', 'functional', 'advertisement']."
},
"domainsApplied": {
"type": "array",
"items": {
"type": "string",
"description": "Each domain for which consent action applies.",
"maxLength": 1024
},
"minItems": 1,
"description": "The domains for which this consent allows these preferences to persist to."
},
"gdprApplies": {
"type": [
"boolean",
"null"
],
"description": "Determine if GDPR applies based on the user's geo-location."
}
},
"required": [
"eventType",
"consentVersion",
"domainsApplied",
"consentScopes",
"consentUrl",
"basisForProcessing"
],
"additionalProperties": false
}
Warehouse query
- Snowflake
- BigQuery
- Databricks
- Redshift & Postgres
select
unstruct_event_com_snowplowanalytics_snowplow_consent_preferences_1 consent_preferences_1
from
atomic.events
where
events.collector_tstamp > getdate() - interval '1 hour'
and events.event = 'unstruct'
and events.event_name = 'consent_preferences'
and events.event_vendor = 'com.snowplowanalytics.snowplow'
select
unstruct_event_com_snowplowanalytics_snowplow_consent_preferences_1_0_0
from
PIPELINE_NAME.events events
where
events.collector_tstamp > timestamp_sub(current_timestamp(), interval 1 hour)
and events.event = 'unstruct'
and events.event_name = 'consent_preferences'
and events.event_vendor = 'com.snowplowanalytics.snowplow'
select
unstruct_event_com_snowplowanalytics_snowplow_consent_preferences_1
from
atomic.events events
where
events.collector_tstamp > timestampadd(HOUR, -1, current_timestamp())
and events.event = 'unstruct'
and events.event_name = 'consent_preferences'
and events.event_vendor = 'com.snowplowanalytics.snowplow'
and unstruct_event_com_snowplowanalytics_snowplow_consent_preferences_1 is not null
select
"consent_preferences_1".*
from
atomic.events events
join atomic.com_snowplowanalytics_snowplow_consent_preferences_1 "consent_preferences_1"
on "consent_preferences_1".root_id = events.event_id and "consent_preferences_1".root_tstamp = events.collector_tstamp
where
events.collector_tstamp > getdate() - interval '1 hour'
and "consent_preferences_1".root_tstamp > getdate() - interval '1 hour'
and events.event = 'unstruct'
and events.event_name = 'consent_preferences'
and events.event_vendor = 'com.snowplowanalytics.snowplow'
cmp_visible
EventExample
{
"elapsedTime": 1.5
}
Properties and schema
- Table
- JSON schema
| Property | Description |
|---|---|
elapsedTimenumber | Required. The time taken for the consent popup to be shown to the screen. |
{
"$schema": "http://iglucentral.com/schemas/com.snowplowanalytics.self-desc/schema/jsonschema/1-0-0#",
"description": "Schema for consent dialog shown event",
"self": {
"vendor": "com.snowplowanalytics.snowplow",
"name": "cmp_visible",
"format": "jsonschema",
"version": "1-0-0"
},
"type": "object",
"properties": {
"elapsedTime": {
"type": "number",
"description": "The time taken for the consent popup to be shown to the screen.",
"maximum": 9223372036854776000,
"minimum": 0
}
},
"required": [
"elapsedTime"
],
"additionalProperties": false
}
Warehouse query
- Snowflake
- BigQuery
- Databricks
- Redshift & Postgres
select
unstruct_event_com_snowplowanalytics_snowplow_cmp_visible_1 cmp_visible_1
from
atomic.events
where
events.collector_tstamp > getdate() - interval '1 hour'
and events.event = 'unstruct'
and events.event_name = 'cmp_visible'
and events.event_vendor = 'com.snowplowanalytics.snowplow'
select
unstruct_event_com_snowplowanalytics_snowplow_cmp_visible_1_0_0
from
PIPELINE_NAME.events events
where
events.collector_tstamp > timestamp_sub(current_timestamp(), interval 1 hour)
and events.event = 'unstruct'
and events.event_name = 'cmp_visible'
and events.event_vendor = 'com.snowplowanalytics.snowplow'
select
unstruct_event_com_snowplowanalytics_snowplow_cmp_visible_1
from
atomic.events events
where
events.collector_tstamp > timestampadd(HOUR, -1, current_timestamp())
and events.event = 'unstruct'
and events.event_name = 'cmp_visible'
and events.event_vendor = 'com.snowplowanalytics.snowplow'
and unstruct_event_com_snowplowanalytics_snowplow_cmp_visible_1 is not null
select
"cmp_visible_1".*
from
atomic.events events
join atomic.com_snowplowanalytics_snowplow_cmp_visible_1 "cmp_visible_1"
on "cmp_visible_1".root_id = events.event_id and "cmp_visible_1".root_tstamp = events.collector_tstamp
where
events.collector_tstamp > getdate() - interval '1 hour'
and "cmp_visible_1".root_tstamp > getdate() - interval '1 hour'
and events.event = 'unstruct'
and events.event_name = 'cmp_visible'
and events.event_vendor = 'com.snowplowanalytics.snowplow'
Basic
When you track a consent_granted or consent_withdrawn event, the tracker will automatically create and attach a consent_document entity.
The native mobile and Flutter trackers also support automatic addition of the gdpr entity to all tracked events. To configure this, provide a GdprConfiguration object when setting up a new tracker.
The React Native tracker did include GDPR entity configuration in earlier versions. We deprecated it in version 4.
consent_granted
SchemaProperties and schema
- Table
- JSON schema
| Property | Description |
|---|---|
expirystring | Optional. |
{
"$schema": "http://iglucentral.com/schemas/com.snowplowanalytics.self-desc/schema/jsonschema/1-0-0#",
"description": "Schema for consent granted",
"self": {
"vendor": "com.snowplowanalytics.snowplow",
"name": "consent_granted",
"format": "jsonschema",
"version": "1-0-0"
},
"type": "object",
"properties": {
"expiry": {
"type": "string",
"format": "date-time"
}
},
"additionalProperties": false
}
consent_withdrawn
SchemaProperties and schema
- Table
- JSON schema
| Property | Description |
|---|---|
allboolean | Required. |
{
"$schema": "http://iglucentral.com/schemas/com.snowplowanalytics.self-desc/schema/jsonschema/1-0-0#",
"description": "Schema for consent withdrawn",
"self": {
"vendor": "com.snowplowanalytics.snowplow",
"name": "consent_withdrawn",
"format": "jsonschema",
"version": "1-0-0"
},
"type": "object",
"properties": {
"all": {
"type": "boolean"
}
},
"required": [
"all"
],
"additionalProperties": false
}
consent_document
SchemaProperties and schema
- Table
- JSON schema
| Property | Description |
|---|---|
idstring | Required. |
versionstring | Required. |
namestring | Optional. |
descriptionstring | Optional. |
{
"$schema": "http://iglucentral.com/schemas/com.snowplowanalytics.self-desc/schema/jsonschema/1-0-0#",
"description": "Schema for consent document context",
"self": {
"vendor": "com.snowplowanalytics.snowplow",
"name": "consent_document",
"format": "jsonschema",
"version": "1-0-0"
},
"type": "object",
"properties": {
"id": {
"type": "string",
"maxLength": 36
},
"version": {
"type": "string",
"maxLength": 36
},
"name": {
"type": "string",
"maxLength": 60
},
"description": {
"type": "string",
"maxLength": 10000
}
},
"required": [
"id",
"version"
],
"additionalProperties": false
}
gdpr
SchemaProperties and schema
- Table
- JSON schema
| Property | Description |
|---|---|
basisForProcessingstring | Required. GDPR basis for data collection & processing Must be one of: consent, contract, legal_obligation, vital_interests, public_task, legitimate_interests |
documentIdstring | Optional. ID for document detailing basis for processing |
documentVersionstring | Optional. Version of document detailing basis for processing |
documentDescriptionstring | Optional. Description of document detailing basis for processing |
{
"$schema": "http://iglucentral.com/schemas/com.snowplowanalytics.self-desc/schema/jsonschema/1-0-0#",
"description": "Schema for a web page context",
"self": {
"vendor": "com.snowplowanalytics.snowplow",
"name": "gdpr",
"format": "jsonschema",
"version": "1-0-0"
},
"type": "object",
"properties": {
"basisForProcessing": {
"type": "string",
"enum": [
"consent",
"contract",
"legal_obligation",
"vital_interests",
"public_task",
"legitimate_interests"
],
"description": "GDPR basis for data collection & processing"
},
"documentId": {
"type": [
"string",
"null"
],
"maxLength": 255,
"description": "ID for document detailing basis for processing"
},
"documentVersion": {
"type": [
"string",
"null"
],
"maxLength": 16,
"description": "Version of document detailing basis for processing"
},
"documentDescription": {
"type": [
"string",
"null"
],
"maxLength": 4096,
"description": "Description of document detailing basis for processing"
}
},
"required": [
"basisForProcessing"
],
"additionalProperties": false
}