Consent management
Overview
The Chord CDP enforces user consent before forwarding events to destinations. When a destination has consent requirements configured, no event is sent to that destination — and no destination script is loaded in the browser — until the user has granted the required consent categories.
This document explains how consent categories are defined, how the CDP receives consent decisions from the browser, and how those decisions gate event delivery in both device mode and cloud mode.
The Consent Lifecycle in Brief
What happens, in order, on a visit to a storefront with a CMP configured:
- Before the CMP publishes a consent state, events are held in a browser queue and nothing reaches Chord. This covers the time the CMP script takes to load — not the time the visitor spends reading the banner.
- Once the CMP publishes a state, the queue flushes. That first state is the jurisdiction default the CMP is configured with: typically permissive under an opt-out model (common in the US) and denied-except-strictly-necessary under an opt-in model (common in the UK and EU).
- From that point on, every event is sent to Chord — whether consent was granted or denied. A denial is recorded on the event; it does not stop collection. Enforcement happens per destination, not in the browser's decision to send.
- Consent is read fresh and stamped immediately before each send, including when a queued event is replayed. A queued event can therefore carry the visitor's actual choice rather than the default it was queued under.
- When the visitor changes their choice, the new preferences apply to every later event, and Chord Pixel fires a Consent Preferences Updated event. That event bypasses consent requirements and reaches every destination, so a destination can act on a revocation.
- Chord decides delivery per destination. A destination receives an event only if every category in its Consent Requirements is true. A destination with an empty requirements list receives everything.
- Nothing is retroactive. Events already delivered under a permissive default stay delivered.
- All of the above requires the consent option to be set when Chord Pixel is initialized. Without it there is no queue and no consent stamp — events are collected and forwarded with no consent data at all.
What a Full Denial Does — and Doesn't — Stop
If a visitor declines every category in the CMP banner, the browser still sends every event to Chord. Collection does not stop. Each event carries categoryPreferences with every category set to false, and Chord records it like any other event.
What stops is delivery:
- A destination with one or more Consent Requirements receives nothing. In device mode, its third-party script is never loaded.
- A destination with an empty Consent Requirements list still receives every event. A full denial does not gate it — configuring the requirements list is what makes consent enforceable for that destination.
- Consent Preferences Updated still reaches every destination, so a platform can act on the revocation.
If you need collection itself to stop, your storefront has to stop calling Chord Pixel. No setting in the Console turns a denial into non-collection.
Consent Categories
Consent categories are the units of permission that users grant or deny. Before configuring consent requirements on a destination, you must define your categories in the Chord Console under CDP → Consent Categories.
Each category has:
- Name — human-readable label shown in the Console
- External ID — the category identifier used by your consent management platform (CMP). Must match exactly what your CMP emits.
- Description — optional explanation of what data collection this category covers
- Active — whether this category is currently enforced
The External ID is the field that connects CDP categories to your CMP. For example, OneTrust uses category codes like C0002 for analytics cookies — the External ID for your analytics category must be set to C0002 for the mapping to work.
Consent Management Platform (CMP) Integration
Chord Pixel bridges your CMP and the CDP. It reads the user's current consent state from the CMP, stamps each outgoing event with the user's category preferences, and updates those stamps dynamically as consent changes.
Support CMPs
- OneTrust — detected via window.OneTrust; categories read from window.OnetrustActiveGroups
- Cookiebot — detected via window.Cookiebot
- Ketch — detected via window.ketch and window.ketchConsent
- Shopify — detected via window.Shopify.customerPrivacy
- Segment — detected via window.segmentConsent
The CMP integration is configured when you initialize Chord Pixel:
const chord = new ChordAnalytics({
consent: 'onetrust', // 'cookiebot' | 'ketch' | 'onetrust' | 'shopify' | 'segment'
awaitConsent: true,
cdpDomain: process.env.CHORD_DOMAIN,
cdpWriteKey: process.env.CHORD_WRITE_KEY,
// rest of your configuration
})If the consent option is not set, Chord Pixel does not read your CMP at all. Events are still collected and forwarded, but they carry no consent information — see Events with no consent data below.
Consent Readiness and Event Queueing
When a CMP is configured, Chord Pixel checks whether that CMP has published a consent state before sending each event. If it has not, the event is held in a queue rather than being dropped. Chord Pixel polls every 100 ms and flushes the queue as soon as the state is available.
This queue covers the short window while the CMP script is still loading — not the period before the visitor answers the banner. Most CMPs publish a default state as soon as they load, so events typically resume immediately, stamped with those defaults rather than with the visitor's eventual choice. OneTrust, for example, is considered ready once window.OnetrustActiveGroups is populated, which happens before any banner interaction.
The queue is held in memory and is not capped. It is also mirrored to sessionStorage so it survives navigation within the session; that mirror keeps only the most recent 50 events and is skipped entirely if it would exceed 100 KB. There is no time-based expiry — queued events are delivered whenever the CMP state becomes available.
Setting awaitConsent: true additionally defers consent setup until the CMP itself has loaded. Chord Pixel polls every 50 ms and gives up after 60 seconds; override that with awaitConsentTimeout (in milliseconds). If the CMP never loads within that window, consent setup is abandoned and subsequent events are sent without a consent stamp.
Consent Stamping
On every event, Chord Pixel fetches the user's current category preferences directly from the CMP (no caching). The result is added to the event under context.consent.categoryPreferences:
{
"context": {
"consent": {
"categoryPreferences": {
"C0001": true,
"C0002": true,
"C0003": false
}
}
}
}The keys in categoryPreferences are the External IDs of your consent categories. Values are true (granted) or false (denied).
Note that denying consent does not stop Chord Pixel from sending the event. The event is still collected, stamped with the denial, and forwarded to the CDP, where consent requirements decide which destinations receive it. This preserves a record of the decision and lets enforcement stay configurable.
Configuring Consent Requirements on a Destination
Open the destination's configuration in the Chord Console and add one or more consent categories to the Consent Requirements list. Each required category must resolve to true in the event's categoryPreferences for the event to be forwarded.
A destination with an empty Consent Requirements list receives every event that passes host and event filters, whatever the user's consent preferences say. Stamping consent on an event does nothing by itself — the categories have to be configured here as well.
Requiring all consent categories
Consent requirements use AND logic: if you specify two categories, both must be granted. There is no OR operator — if you want a destination to fire when any one of several categories is granted, create separate destination configurations.
Events with no consent data: the Send Null Consent Events option
By default, if an event arrives with no categoryPreferences at all, the destination treats consent as implicitly granted and forwards the event. This preserves backward compatibility for destinations that predate consent configuration.
Events arrive with no consent data in two common situations:
- A storefront that has no CMP configured in Chord Pixel.
- Server-to-server sources such as Shopify webhooks. Consent APIs are browser APIs, so a webhook carries no consent signal.
To block those events, disable Send Null Consent Events on the destination configuration. With this option disabled, any event that lacks categoryPreferences is dropped, regardless of what consent requirements are set:
- No categoryPreferences, option enabled (the default) — event forwarded
- No categoryPreferences, option disabled — event dropped
- categoryPreferences present — consent requirements are evaluated, and this option is not consulted
The option is a property of the destination, so it applies to every source connected to that destination. It cannot be scoped to one source. If you need to block server-side events while continuing to accept browser events that carry no consent data, configure a separate destination for the server-side traffic.
How Consent Gates Event Delivery
Device-mode
Device mode destinations run as browser plugins — the destination's third-party script (e.g., a pixel or SDK) loads in the visitor's browser, and events are sent directly from the browser to the destination's servers.
Before any device mode plugin processes an event, the CDP SDK calls applyFilters(), which:
- Checks host and event-type filters (unrelated to consent)
- If the destination has consentRequirements, evaluates them against the event's categoryPreferences
- Returns false if any required category is not granted
When applyFilters() returns false, the plugin's handler is never invoked. The event is silently dropped for that destination.
Third-party scripts are loaded lazily. A device mode destination's script is only loaded after the first event passes all filters, including consent. If the user never grants the required consent, the destination script is never injected into the page.
Cloud-mode
Cloud mode destinations receive events server-side via the Chord CDP pipeline. The same consent logic runs in the pipeline before the event is dispatched to the destination function. Events that do not satisfy the consent requirements are dropped before the destination function executes.
The Consent Preferences Updated Event
When a user changes their consent choices, Chord Pixel fires a Consent Preferences Updated event. This event always bypasses consent requirements and is forwarded to all destinations regardless of current category preferences.
This allows destinations to register the updated preferences — for example, to update suppression lists or unsubscribe records in a marketing platform — even when the user has revoked consent for that destination's category.
Example: SFMC Collect.js
Salesforce Marketing Cloud Collect.js is a device mode destination. If it is configured with a consent requirement of C0002 (analytics cookies):
- A visitor arrives and has not yet interacted with the consent banner — no categoryPreferences in events. If Send Null Consent Events is enabled (the default), events flow to SFMC. If it is disabled, events are held until consent is given.
- The visitor dismisses the banner and denies analytics cookies — categoryPreferences: { "C0002": false }. All subsequent events for SFMC are dropped. The Collect.js script is not loaded if it hasn't been already.
- The visitor accepts analytics cookies — categoryPreferences: { "C0002": true }. Events resume flowing to SFMC. If the Collect.js script was never loaded, it is loaded now on the next passing event.
- The visitor later revokes consent. A Consent Preferences Updated event is fired and delivered to SFMC regardless of the new consent state. All subsequent track and page events are again blocked.
Troubleshooting
Events are not reaching a destination even though consent was granted. Check that the External IDs configured on your consent categories in the Chord Console exactly match the category codes your CMP emits. A mismatch (e.g., c0002 vs C0002) causes every event to fail the consent check.
Events are flowing to a destination even though the user denied consent. Verify that the destination has consent requirements configured. A destination with no consent requirements set will receive all events that pass host and event filters, regardless of the user's consent preferences.
Events arrive with no consent object at all. Confirm that the consent option is set when Chord Pixel is initialized. Without it, Chord Pixel never reads your CMP, and every event is treated as having no consent data.
The destination script loads before consent is given. This indicates that at least one event is passing the consent filter before consent is granted — most likely because categoryPreferences is absent and Send Null Consent Events is enabled. Disable that option on the destination if you require explicit opt-in before the script loads.
Updated 22 September 2026