Many teams expect their CMP (Axeptio, Didomi, OneTrust, Cookiebot…) to push one “consent dataLayer” that every tag manager understands. That object doesn’t exist. Each analytics or ads library reads consent through its own API, and some of them can also read the IAB TCF string directly. The useful question is not “does my tag manager read TCF?” but “what does each tag read, and who sets it?”

1. What a CMP does

A CMP shows the banner, stores the visitor’s choice, and exposes it. Depending on the CMP and its settings, it exposes it through:

TCF is a standardised way to record and share consent choices. Using it does not make a site GDPR-compliant by itself.

2. Google tags: consent mode, or TCF

Consent mode. The page sets a default before any Google tag sends data, then the CMP updates it when the visitor chooses. Google: “The order of the code here is vital. If your consent code is called out of order, consent defaults won’t work.”

// 1. Before any measurement command, on every page
gtag('consent', 'default', {
  'ad_storage': 'denied',
  'ad_user_data': 'denied',
  'ad_personalization': 'denied',
  'analytics_storage': 'denied'
});

// 2. When the visitor makes a choice (usually done by the CMP)
gtag('consent', 'update', {
  'ad_storage': 'granted',
  'ad_user_data': 'granted',
  'ad_personalization': 'granted',
  'analytics_storage': 'granted'
});

A denied default is the intended setup, not an error. ad_user_data and ad_personalization were added in consent mode v2. In Google Tag Manager, Google recommends letting a CMP handle the updates; many CMPs publish a Community Template that sets both the default and the update.

TCF. Google tags can also read the TC string natively. Enable it with window['gtag_enable_tcf_support'] = true on the site, or with enableAdvertiserConsentMode: true in the CMP’s TCData. The Google tag then maps TCF purposes to consent mode:

TCF purpose denied Effect
Purpose 1 ad_storage and ad_user_data denied
Purpose 3 or 4 ad_personalization denied
Purpose 7 ad_user_data denied
Purpose 9 or 10 Google signals disabled in GA4 (web)

If the CMP doesn’t respond within 500 milliseconds, the tag uses the default consent settings.

3. Adobe: two paths, depending on the library

Legacy AppMeasurement and ECID: the Opt-In Service. The categories are fixed:

adobe.OptInCategories = {
  "AAM": "aam",
  "ANALYTICS": "aa",
  "ECID": "ecid",
  "TARGET": "target"
}

adobe.optIn.approve(['aa', 'ecid']);
adobe.optIn.deny(['target']);

Note the analytics category is aa, not analytics. If you pass shouldWaitForComplete = true, nothing is applied until you call adobe.optIn.complete().

Web SDK (alloy): setConsent. It accepts Adobe’s own standard (1.0 or 2.0) or an IAB TCF string:

alloy("setConsent", {
  consent: [{
    "standard": "IAB TCF",
    "version": "2.0",
    "value": tcString,       // from __tcfapi
    "gdprApplies": true
  }]
});

// or, with Adobe's standard 1.0
alloy("setConsent", {
  consent: [{ "standard": "Adobe", "version": "1.0", "value": { "general": "in" } }]
});

The tag manager itself is Adobe Experience Platform Tags (formerly Launch). It deploys either library; the consent path depends on which one you use.

4. Matomo: one API, two modes

Matomo’s consent guide documents its own _paq API. Pick one mode, and use the matching calls:

Mode Before consent Give / remember Withdraw
requireConsent No tracking request, no cookie rememberConsentGiven forgetConsentGiven
requireCookieConsent Requests sent, no cookie rememberCookieConsentGiven forgetCookieConsentGiven

5. Summary

Library Reads the TC string? Consent API
Google tag (GA4, Ads, Floodlight) Yes, once TCF support is enabled gtag('consent', 'default' / 'update', …)
Adobe AppMeasurement + ECID No adobe.optIn.approve / deny (aa, ecid, target, aam)
Adobe Web SDK Yes, passed to setConsent alloy("setConsent", …)
Matomo Not in its consent guide _paq consent calls

6. When you need a mapping script

If your CMP already sets Google consent mode (or you enabled TCF support) and you use the Adobe Web SDK with the TC string, there may be little to map. For legacy Adobe and for Matomo, you usually need a small script that listens to the CMP and calls the right API:

// cmpConsent: whatever your CMP exposes (callback, event, TCF purposes...)
function applyConsent(cmpConsent) {
  if (cmpConsent.analytics) {
    adobe.optIn.approve(['aa', 'ecid']);
    _paq.push(['rememberConsentGiven']);
  } else {
    adobe.optIn.deny(['aa', 'ecid']);
    _paq.push(['forgetConsentGiven']);
  }
}

Always check what your CMP actually sends, in Tag Assistant for Google and in the browser console for the others, before writing any mapping.

7. Common mistakes

Related reading

Sources

Not sure your own tracking is right?

Book a call Or start with the free analytics audit →