User Tools

Site Tools


privacy:tcf_consent_strings

Decoding TCF Consent Strings

A European site with a banner usually writes down what it thinks you agreed to, in a format that a machine can read: a TC string under IAB Europe's Transparency and Consent Framework, and often a second, much less studied Additional Consent (AC) string invented by Google for the vendors the TCF does not cover. Both are visible to a crawler. Decoding them turns “did the site respect my choice?” from a question about pixels and cookies into a question about two byte arrays. That is why the slice of the compliance literature that audits recording rather than behaviour is almost entirely TCF work — though, as this page's own corpus section shows, that slice is very small.

This page is about those strings as measurement artefacts: where they are, how to decode one so that the decode is still reproducible next year, and — the part that gets papers rejected — what a decoded string does and does not license you to claim. Whether your crawler should click Accept or Reject at all, how to find the banner, and what the wider consent-signal landscape looks like are on Granting Consent to Websites; this page starts after the choice is made.

Three things to fix before you write a sentence about a TC string.

  • The string is a record made by the CMP, not a record made by the user. It says what a Consent Management Platform asserts it collected. Every step between the user's click and the vendor's behaviour is a separate empirical question, and the corpus has papers showing each of them broken: of the 136 TCF sites offering revocation that [1Kancherla, Gayatri Priyadarsini; Bielova, Nataliia; Santos, Cristiana; Bichhawat, Abhishek (2025): "Johnny Can't Revoke Consent Either: Measuring Compliance of Consent Revocation on the Web", in: Proceedings on Privacy Enhancing Technologies. (DOI)] studied, 17 returned positive consent through __tcfapi after the user revoked, and on 101 (74.2%) at least one third party was told about the acceptance and never told about the revocation.
  • A decoded vendor set is meaningless without the Global Vendor List version it was decoded against. The GVL is republished weekly and vendor IDs are only stable relative to a version number, which the string itself carries. Fetch and archive the GVL alongside the crawl; do not resolve IDs months later.
  • The reference decoder moved npm scope and did not leave a forwarding address. npm install @iabtcf/core still succeeds, still carries no deprecation notice, and installs 1.5.6 from 2023-04-04. The maintained package is @iabtechlabtcf/core, currently 1.5.21 (2026-02-10), from the same repository.1) They decode differently — see below. Name the package and the version in your paper.

What to Read First

  • Do Cookie Banners Respect my Choice? [2Matte, Célestin; Bielova, Nataliia; Santos, Cristiana Teixeira (2020): "Do Cookie Banners Respect my Choice? Measuring Legal Compliance of Banners from IAB Europe's Transparency and Consent Framework", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)], IEEE S&P 2020 — the paper that made the TC string the unit of analysis. It is the origin of the four-violation taxonomy and of the practice of reading the stored string instead of the banner. Date it: it measures TCF v1.1, whose __cmp() API, shared consensu.org cookie and five-purpose model have all been retired. The method survived; the mechanics did not.
  • A Study of GDPR Compliance under the Transparency and Consent Framework [3Smith, Michael; Torres-Agüero, Antonio; Grossman, Riley; Sen, Pritam; Chen, Yi; Borcea, Cristian (2024): "A Study of GDPR Compliance under the Transparency and Consent Framework", in: Proceedings of the ACM Web Conference. (DOI)], TheWebConf 2024 — the cleanest published description of an end-to-end TC-string pipeline: find strings in requests and cookies, decode, validate, aggregate per domain. Read it for the pipeline and for the finding that the IAB decoder will happily decode strings that are not TC strings.
  • Johnny Can't Revoke Consent Either [1Kancherla, Gayatri Priyadarsini; Bielova, Nataliia; Santos, Cristiana; Bichhawat, Abhishek (2025): "Johnny Can't Revoke Consent Either: Measuring Compliance of Consent Revocation on the Web", in: Proceedings on Privacy Enhancing Technologies. (DOI)], PETS 2025 — the paper to read for where strings hide. It is the only one in this corpus that systematically compares the string in the browser against the strings actually leaving it, in POST bodies, JSON responses and HTML.
  • The TCF doesn't really A(A)ID [4Morel, Victor; Santos, Cristiana; Carlsson, Pontus; Ahlinder, Joel; Duvignau, Romaric (2026): "The TCF doesn't really A(A)ID - Automatic Privacy Analysis and Legal Compliance of TCF-based Android Applications", Proceedings on Privacy Enhancing Technologies 2026(3). (DOI)], PETS 2026 — the framework in Android apps, where the string lives in SharedPreferences under IABTCF_* keys rather than in a cookie. The first study to decode what a mobile CMP stores — [5Koch, Simon; Altpeter, Benjamin; Johns, Martin (2023): "The OK Is Not Enough: A Large Scale Study of Consent Dialogs in Smartphone Applications", in: Proceedings of the USENIX Security Symposium. (Link)] had already counted apps setting IABTCF_ keys three years earlier, but not read the values. The web methods do not transfer unchanged.
  • Privacy Preference Signals: Past, Present and Future [6Hils, Maximilian; Woods, Daniel W.; Böhme, Rainer (2021): "Privacy Preference Signals: Past, Present and Future", in: Proceedings on Privacy Enhancing Technologies. (DOI)], PETS 2021 — for the framing question of why an industry consent signal exists at all, and for adoption measured longitudinally rather than in one snapshot.
  • The specifications themselves are short and are the only authority that matters for the format: the TC string and GVL format spec and the CMP API spec, both maintained by IAB Tech Lab on GitHub, and Google's Additional Consent technical specification in the Ad Manager help centre.2)

What a TC String Is, as a Measurement Artefact

The three segments

A TC string is dot-separated web-safe base64. Segment 0 is the Core String and is always present. Later segments carry a 3-bit segment type in their first bits, so they can appear in any order:

Segment Type Status What it holds Why a measurement cares
Core mandatory metadata, per-purpose consent and legitimate interest, per-vendor consent and legitimate interest, publisher restrictions This is where almost every published figure comes from
Disclosed Vendors 1 mandatory since TCF v2.3 (was optional) which vendors the CMP says it showed the user Distinguishes “not disclosed” from “disclosed and refused” — before v2.3 those were the same blank
Allowed Vendors 2 gone — the current spec's SegmentType enum lists only 0, 1 and 3 out-of-band allowed vendors, which went with the deprecation of out-of-band consent in 2021 You may meet it in archived strings; a decoder that errors on an unknown segment type will choke on them
Publisher TC 3 optional the publisher's own purposes, including custom ones Vendors are told not to rely on it unless they have an agreement with the publisher; treat it as publisher self-description

A string with only one segment is either pre-v2.3 or non-conformant. Count segments before you conclude anything about disclosure.

The fields that decide your numbers

The Core String is a fixed bit layout. These are the fields that change what a paper can claim; the full table is in the spec.

Field Bits What it actually tells you
Version 6 2 for every string you will meet today. A v1 string is invalid since 30 September 2020
Created / LastUpdated 36 each Both carry the same day-level value since December 2021. You cannot tell a first choice from a re-confirmation, and you cannot recover a time of day
CmpId 12 Which CMP says it wrote the string. Joins to the Global CMP List. Not authenticated
CmpVersion , ConsentScreen 12 , 6 CMP self-report. Useful for grouping, useless as ground truth
ConsentLanguage 12 The language the CMP says the UI was in — not the site's language and not the user's
VendorListVersion 12 The GVL version every vendor ID in this string must be resolved against
TcfPolicyVersion 6 Policy generation. 4 = TCF v2.2, 5 = v2.3 and later. This is how you bucket a longitudinal dataset
IsServiceSpecific 1 Should be 1. A 0 means a global-scope string, which has been invalid since 1 September 2021
UseNonStandardTexts 1 The CMP is telling you it did not show the standard purpose descriptions
PurposesConsent 24 One bit per purpose. 11 purposes exist since TCF v2.2; papers written against v2.1 and earlier describe 10
PurposesLITransparency 24 Legitimate interest established and not objected to. Not consent
PurposeOneTreatment 1 1 means Purpose 1 was not disclosed because the publisher's jurisdiction does not require it. A 0 in PurposesConsent bit 1 then does not mean refusal
PublisherCC 12 The publisher's establishment or “the legislative country of reference” — the spec allows either. See the caveat below: in an eight-site probe it tracked the crawler's IP
vendor sections variable Either a bitfield up to MaxVendorId or run-length ranges. Both encode the same thing; a decoder that handles only one silently returns an empty set

Version history, and which version your data is

Every figure about the TCF is a figure about one version of it. This is the specification's own changelog, re-fetched on 2026-08-26, filtered to changes a measurement can see — two v2.1 rows about a JSON example and a document merge are dropped:

Date Version What changed that a measurement can see
April 2018 1.1 __cmp() API, five purposes, euconsent cookie on consensu.org
August 2019 2.0 __tcfapi, ten purposes, publisher restrictions, segments
June 2021 → 1 Sept 2021 2.0 Global scope, out-of-band consent and the shared consensu.org cookie deprecated; global-scope strings invalid from 1 September 2021
December 2021 2.0 Created and LastUpdated collapsed to one day-level value
May 2023 2.2 Eleven purposes; legitimate interest removed for purposes 3–6; getTCData API command deprecated; policy version 4, older strings invalid after 30 September 2023
February 2024 2.2 gdpr_pd macro deprecated; environments field added to the CMP list
April 2025 2.3 Disclosed Vendors segment mandatory, replacing the workaround of setting the vendor LI bit for special-purpose-only vendors. The changelog dates the workaround's end to strings created on or after 1 March 2026; it puts no date on the segment itself becoming mandatory, and this page assumes the same boundary because they are the same change3)
May 2026 2.4 StandardTexts field added to the GVL JSON; the text requiring special-purpose-only vendors to be disclosed under the Legitimate Interest declaration removed from the spec

Two consequences for anyone crawling now. A dataset that spans 1 March 2026 spans two different meanings of the vendor legitimate-interest bit: before that date it was also set for vendors that declared only special purposes, so a naive “share of vendors asserting legitimate interest” is inflated on the early side of the boundary and not on the late side. And a dataset that spans May 2023 spans the change from ten purposes to eleven and the removal of legitimate interest for purposes 3–6, which is exactly the quantity [3Smith, Michael; Torres-Agüero, Antonio; Grossman, Riley; Sen, Pritam; Chen, Yi; Borcea, Cristian (2024): "A Study of GDPR Compliance under the Transparency and Consent Framework", in: Proceedings of the ACM Web Conference. (DOI)] measured under the old rules.

Where the String Lives: Seven Channels, and What Each Proves

The TCF has never required one storage location — v2 explicitly leaves it to the CMP, including non-cookie storage. Reading only one channel is the single most common way to under-count.

Channel How you capture it What it proves Seen in
CMP JavaScript APIwindow.__tcfapi, or the __tcfapiLocator iframe for third-party frames inject a script, register an addEventListener callback what the CMP will tell a first-party script right now [2Matte, Célestin; Bielova, Nataliia; Santos, Cristiana Teixeira (2020): "Do Cookie Banners Respect my Choice? Measuring Legal Compliance of Banners from IAB Europe's Transparency and Consent Framework", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI), 1Kancherla, Gayatri Priyadarsini; Bielova, Nataliia; Santos, Cristiana; Bichhawat, Abhishek (2025): "Johnny Can't Revoke Consent Either: Measuring Compliance of Consent Revocation on the Web", in: Proceedings on Privacy Enhancing Technologies. (DOI)]
First-party storage — a cookie or localStorage key of the CMP's choosing read cookie jar and localStorage after load what persists to the next visit TCString in first-party cookies on 122 of 136 TCF sites [1Kancherla, Gayatri Priyadarsini; Bielova, Nataliia; Santos, Cristiana; Bichhawat, Abhishek (2025): "Johnny Can't Revoke Consent Either: Measuring Compliance of Consent Revocation on the Web", in: Proceedings on Privacy Enhancing Technologies. (DOI)]
URL macros on GETgdpr=1 and gdpr_consent=${GDPR_CONSENT_<vendorId>} log outgoing request URLs what a named vendor was actually sent GET on 764 of 1,426 (53.6%) TCF sites [2Matte, Célestin; Bielova, Nataliia; Santos, Cristiana Teixeira (2020): "Do Cookie Banners Respect my Choice? Measuring Legal Compliance of Banners from IAB Europe's Transparency and Consent Framework", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)]
POST bodies log postData, not just URLs the same, for vendors that POST 3,423 TC strings found in POST bodies in one crawl [1Kancherla, Gayatri Priyadarsini; Bielova, Nataliia; Santos, Cristiana; Bichhawat, Abhishek (2025): "Johnny Can't Revoke Consent Either: Measuring Compliance of Consent Revocation on the Web", in: Proceedings on Privacy Enhancing Technologies. (DOI)]; POSTs carried a string on 399 sites in 2019 [2Matte, Célestin; Bielova, Nataliia; Santos, Cristiana Teixeira (2020): "Do Cookie Banners Respect my Choice? Measuring Legal Compliance of Banners from IAB Europe's Transparency and Consent Framework", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)]
HTTP responses — JSON and HTML parse response bodies whether a third party changed the string before passing it on 52 in JSON, 170 in HTML [1Kancherla, Gayatri Priyadarsini; Bielova, Nataliia; Santos, Cristiana; Bichhawat, Abhishek (2025): "Johnny Can't Revoke Consent Either: Measuring Compliance of Consent Revocation on the Web", in: Proceedings on Privacy Enhancing Technologies. (DOI)]
Mobile app storageIABTCF_TCString, IABTCF_PurposeConsents, IABTCF_PurposeLegitimateInterests, IABTCF_CmpSdkID in Android SharedPreferences or iOS NSUserDefaults pull the app's preferences file off a rooted device or emulator the in-app equivalent, and the only channel that exists there [4Morel, Victor; Santos, Cristiana; Carlsson, Pontus; Ahlinder, Joel; Duvignau, Romaric (2026): "The TCF doesn't really A(A)ID - Automatic Privacy Analysis and Legal Compliance of TCF-based Android Applications", Proceedings on Privacy Enhancing Technologies 2026(3). (DOI), 5Koch, Simon; Altpeter, Benjamin; Johns, Martin (2023): "The OK Is Not Enough: A Large Scale Study of Consent Dialogs in Smartphone Applications", in: Proceedings of the USENIX Security Symposium. (Link)]
Inside a GPP string — section ID 2 of IAB Tech Lab's Global Privacy Platform decode the GPP header, then the TCF-EU section the same string, wrapped, on sites that have migrated to the multi-jurisdiction envelope not measured in this corpus

One channel is historical and must not be reported as current: the shared cookie on the consensu.org domain, euconsent under TCF v1.x and euconsent-v2 under v2.0's optional global scope. Either way a CMP could read a consent string written by a different CMP on a different site, which is how [2Matte, Célestin; Bielova, Nataliia; Santos, Cristiana Teixeira (2020): "Do Cookie Banners Respect my Choice? Measuring Legal Compliance of Banners from IAB Europe's Transparency and Consent Framework", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)] found that “Using this protocol, 62 (4.3%) websites return the same consent strings” after planting one in 2019. IAB Europe announced the deprecation of global scope, out-of-band consent and the euconsent-v2 cookie on 22 June 2021, and global-scope strings have been invalid since 1 September 2021. If you crawl statefully today, a stale consent string is a problem you carry between page loads of the same site, not one you carry between sites via IAB infrastructure.

The API channel needs one specific piece of code, because the command most published crawlers use for it is deprecated. This is the current pattern, and it is what produced the output below:

tcf_capture.js
// Inject BEFORE any page script (Playwright: context.addInitScript).
// Uses addEventListener, not the getTCData command deprecated in TCF v2.2.
// Records EVERY event, so a late 'useractioncomplete' is not lost, and leaves
// a defined-but-silent __tcfapi visible as an empty event list rather than as
// "no TCF".
window.__probe = { events: [] };
(function poll(n) {
  if (typeof window.__tcfapi === 'function') {
    window.__tcfapi('addEventListener', 2, function (d, ok) {
      window.__probe.events.push({
        ok: ok,
        eventStatus: d && d.eventStatus,     // tcloaded | cmpuishown | useractioncomplete
        cmpStatus: d && d.cmpStatus,         // stub | loaded | error
        gdprApplies: d && d.gdprApplies,     // the PUBLISHER's determination, not yours
        cmpId: d && d.cmpId,
        tcfPolicyVersion: d && d.tcfPolicyVersion,
        tcString: d && d.tcString,
        addtlConsent: d && d.addtlConsent,   // Google AC string, if the CMP supports it
      });
    });
    return;
  }
  if (n > 0) setTimeout(function () { poll(n - 1); }, 250);   // 10s for the stub to resolve
})(40);

A worked example, from a real crawl. Eight European news sites, one page load each, no banner interaction, from a residential Swiss vantage point on 2026-08-26. The probe is scripts/tcf_live_probe.mjs and the full output is on the provenance page. Four of the eight answered:

  • spiegel.de (CMP 6, Sourcepoint): a TC string exists before any click, with purposesConsent empty and purposesLITransparency = [7, 9, 10]. That is the specification working as designed — the CMP API says that when the UI is shown it shall create a string with legitimate-interest signals true and consent signals false — and it is why “a TC string exists pre-interaction” is not a violation on its own.
  • corriere.it (CMP 218, RCS MediaGroup): purposesConsent empty, but 932 vendor-consent bits set, all resolving to real vendors in GVL 173. A detector that reads only the purpose array, as [2Matte, Célestin; Bielova, Nataliia; Santos, Cristiana Teixeira (2020): "Do Cookie Banners Respect my Choice? Measuring Legal Compliance of Banners from IAB Europe's Transparency and Consent Framework", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)] explicitly did — “we focus on the purposes stored in a consent string, and do not analyze the array of allowed advertisers” — records nothing here. Which array you read decides whether you see anything.
  • bild.de (CMP 345) and focus.de (CMP 35): empty strings, and both CMP IDs belong to the publisher (Axel Springer, BurdaForward), flagged isCommercial: false in the CMP list. Attributing a behaviour to “the CMP” attributes it to the publisher on these sites.
  • lemonde.fr, elmundo.es, marca.com: __tcfapi is defined and the listener never fires within twelve seconds. Score these as “no TCF” and you have three false negatives out of eight. telegraph.co.uk has no __tcfapi at all from this vantage point.
  • Three of the four strings report PublisherCC = CH, which is where the crawler is, not where Axel Springer, Spiegel or Burda are established. This is not necessarily a defect: the specification defines the field as “the country in which the publisher's business entity is established or the legislative country of reference”, so a CMP that sets it from the visitor's location is arguably using the second reading. But it does mean PublisherCC is not a publisher attribute — do not treat it as one without checking it from a second vantage point.

Decoding It Reproducibly

Do not hand-roll it, and do not trust the library either

The canonical decoder is IAB Tech Lab's iabtcf-es. Use it — and then check which package you installed, because the project renamed its npm scope and left the old one on the registry, undeprecated, three years stale:

npm package Latest Published Deprecated on npm?
@iabtcf/core 1.5.6 2023-04-04 no
@iabtechlabtcf/core 1.5.21 2026-02-10 no

This is not a cosmetic difference, and the failure is silent. Decode the same string with both and they disagree on useNonStandardTexts: the 2026 package exposes it, the 2023 package exposes the field under its old specification name useNonStandardStacks and returns undefined for the current one. Code written against the current spec gets undefined rather than an error, and undefined is falsy. Record the exact package and version in the paper, because a decoder that predates a field does not tell you the field is missing; it returns a default.

The other half of the warning is that a decoder returning a value is not evidence that the input was a TC string. [3Smith, Michael; Torres-Agüero, Antonio; Grossman, Riley; Sen, Pritam; Chen, Yi; Borcea, Cristian (2024): "A Study of GDPR Compliance under the Transparency and Consent Framework", in: Proceedings of the ACM Web Conference. (DOI)] searched requests and cookies for the keys gdpr_consent and euconsent_v2 and the C prefix, then found by hand that “we found 62 decoded strings that were not valid TC strings in TCF v2.1” — including the literal text cookie_banner_accepted — and concluded that “Currently, the IAB decoder lacks a solution for checking if a TC string is valid or not”. Validate structurally: version 2, a plausible VendorListVersion, a TcfPolicyVersion that exists, a PublisherCC that is two letters, and a segment inventory.

The decoder below reads the Core String fields listed above and nothing else, which is the point: it cannot silently disagree with a newer specification about a field it does not touch. It was checked field-by-field against @iabtechlabtcf/core 1.5.21 on the specification's own example string, a 2020-era string, and the four strings captured live on 2026-08-26 — all six agree exactly, on all eighteen fields. Its output is the spiegel.de row of the worked example above.

tcstring.mjs
// Decode the Core segment of a TCF v2 TC String, plus the segment inventory.
//
// Why hand-rolled: the reference implementation is IAB Tech Lab's iabtcf-es,
// published as @iabtechlabtcf/core (1.5.21, 2026-02-10) — NOT @iabtcf/core,
// which is the same project's abandoned npm scope, undeprecated and frozen at
// 1.5.6 from 2023. This reads the fields a measurement actually needs and
// nothing else, so it cannot silently disagree with a newer spec about a field
// it does not touch. Cross-checked field-for-field against 1.5.21 on 6 strings.
//
//   node tcstring.mjs '<tcstring>'
//
// No try/catch: a string that is not a TC string must crash here, not be
// silently reported as "no consent".
 
const B64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
 
function bits(segment) {
  let out = '';
  for (const ch of segment) {
    const i = B64.indexOf(ch);
    if (i < 0) throw new Error(`not web-safe base64: ${JSON.stringify(ch)} in ${segment.slice(0, 20)}`);
    out += i.toString(2).padStart(6, '0');
  }
  return out;
}
const int = (b, s, n) => parseInt(b.slice(s, s + n), 2);
const chars = (b, s, n) => {
  let out = '';
  for (let i = 0; i < n / 6; i++) out += String.fromCharCode(65 + int(b, s + i * 6, 6));
  return out;
};
// Created / LastUpdated are deciseconds since epoch, but since Dec 2021 both
// carry the SAME day-level value: you cannot recover the time of day, and you
// cannot tell a first choice from a re-confirmation.
const day = (b, s) => new Date(int(b, s, 36) * 100).toISOString().slice(0, 10);
 
function vendorSection(b, start) {
  const maxVendorId = int(b, start, 16);
  const isRange = b[start + 16] === '1';
  const ids = new Set();
  let p = start + 17;
  if (!isRange) {
    for (let i = 0; i < maxVendorId; i++) if (b[p + i] === '1') ids.add(i + 1);
    p += maxVendorId;
  } else {
    const n = int(b, p, 12);
    p += 12;
    for (let i = 0; i < n; i++) {
      const isARange = b[p] === '1';
      p += 1;
      const startId = int(b, p, 16);
      p += 16;
      if (isARange) {
        const endId = int(b, p, 16);
        p += 16;
        for (let v = startId; v <= endId; v++) ids.add(v);
      } else ids.add(startId);
    }
  }
  return { maxVendorId, encoding: isRange ? 'range' : 'bitfield', ids, end: p };
}
 
export function decodeCore(tcString) {
  const segments = tcString.split('.');
  const b = bits(segments[0]);
  const core = {
    version: int(b, 0, 6),
    created: day(b, 6),
    lastUpdated: day(b, 42),
    cmpId: int(b, 78, 12),
    cmpVersion: int(b, 90, 12),
    consentScreen: int(b, 102, 6),
    consentLanguage: chars(b, 108, 12),
    vendorListVersion: int(b, 120, 12),
    tcfPolicyVersion: int(b, 132, 6),
    isServiceSpecific: b[138] === '1',
    useNonStandardTexts: b[139] === '1',
    specialFeatureOptIns: [...Array(12)].map((_, i) => b[140 + i] === '1'),
    purposesConsent: [...Array(24)].map((_, i) => b[152 + i] === '1'),
    purposesLITransparency: [...Array(24)].map((_, i) => b[176 + i] === '1'),
    purposeOneTreatment: b[200] === '1',
    publisherCC: chars(b, 201, 12),
  };
  const vc = vendorSection(b, 213);
  const vli = vendorSection(b, vc.end);
  const on = (a) => a.map((v, i) => (v ? i + 1 : 0)).filter(Boolean);
  return {
    ...core,
    specialFeatureOptIns: on(core.specialFeatureOptIns),
    purposesConsent: on(core.purposesConsent),
    purposesLITransparency: on(core.purposesLITransparency),
    vendorConsent: { ...vc, ids: [...vc.ids], end: undefined },
    vendorLegitimateInterest: { ...vli, ids: [...vli.ids], end: undefined },
    segments: segments.map((s, i) => ({
      index: i,
      // Segment 0 is the Core String. Every later segment declares its own type
      // in its first 3 bits. The current spec's SegmentType enum is 0 = Core,
      // 1 = DisclosedVendors, 3 = PublisherTC; 2 = AllowedVendors was dropped
      // with out-of-band consent in 2021 and survives only in archived strings.
      segmentType: i === 0 ? 'core' : int(bits(s), 0, 3),
      length: s.length,
    })),
  };
}
 
if (import.meta.url === `file://${process.argv[1]}`) {
  const s = process.argv[2];
  console.log(JSON.stringify(decodeCore(s), (k, v) => (v === undefined ? undefined : v), 1));
}

Pin the Global Vendor List, and archive it

Vendor IDs mean nothing on their own. The GVL is republished weekly, Thursdays at 17:00 CET, and the string tells you which version it was written against, so a reproducible decode is:

current : https://vendor-list.consensu.org/v3/vendor-list.json
archive : https://vendor-list.consensu.org/v3/archives/vendor-list-v{vendorListVersion}.json

Fetched on 2026-08-26, the current list is version 173, tcfPolicyVersion 5, last updated 2026-08-20, with 1,203 vendors and a highest vendor ID of 1,634 — so about a quarter of the IDs below the maximum resolve to nothing in the current list, whether because the vendor left or because the ID was never issued. That gap is the reason to archive: resolve a 2023 string against today's list and the departed vendors vanish silently rather than erroring. The specification also requires GVL fetches to be server-side and cached to the max-age header, and warns that over-fetching gets you blocked; a crawler that pulls the GVL once per site is doing it wrong and is also generating a distinctive traffic signature.

For scale over time: the list held 751 companies at the end of May 2021 [7Toth, Michael; Bielova, Nataliia; Roca, Vincent (2022): "On dark patterns and manipulation of website publishers by CMPs", Proceedings on Privacy Enhancing Technologies 2022(3). (DOI)] and 684 registered companies in February 2021 [6Hils, Maximilian; Woods, Daniel W.; Böhme, Rainer (2021): "Privacy Preference Signals: Past, Present and Future", in: Proceedings on Privacy Enhancing Technologies. (DOI)], against 1,203 today.

Resolving the CMP ID

CmpId joins to the Global CMP List at https://cmplist.consensu.org/v2/cmp-list.json. On 2026-08-26 it held 264 entries of which 189 are active and 75 carry a deletedDate, with a highest ID of 515. Three consequences: an ID you decode may not be in the current list (join against the whole file, including deleted entries, not just the active ones); the ID space is sparse, so a “not found” is at least as likely to be an invalid string as a new CMP; and the list flags isCommercial, which distinguishes a CMP vendor from a publisher running its own — a distinction that matters the moment you attribute a design choice to “the CMP”, as [7Toth, Michael; Bielova, Nataliia; Roca, Vincent (2022): "On dark patterns and manipulation of website publishers by CMPs", Proceedings on Privacy Enhancing Technologies 2022(3). (DOI)] does.

And the field is not authenticated. [2Matte, Célestin; Bielova, Nataliia; Santos, Cristiana Teixeira (2020): "Do Cookie Banners Respect my Choice? Measuring Legal Compliance of Banners from IAB Europe's Transparency and Consent Framework", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)] found “the following incorrect CMP IDs in consent strings: 1, 0 and 4095” on 155, 45 and 3 websites respectively, at a time when valid IDs ran from 2 to 265, and found “CMP IDs in GET and POST requests different from the ones found using the standard APIs on 48 websites”.

Google Additional Consent: the Parallel Signal Nobody Measures

The TCF only covers vendors registered on the GVL. Google runs a parallel list — Ad Tech Providers (ATPs) — for partners that are not, and a parallel string to carry consent for them. If you are measuring “how many parties did this site get consent for”, ignoring it undercounts by whatever the ATP list contributes, and in the CMP consoles [7Toth, Michael; Bielova, Nataliia; Roca, Vincent (2022): "On dark patterns and manipulation of website publishers by CMPs", Proceedings on Privacy Enhancing Technologies 2022(3). (DOI)] inspected the ATP list held “a total of 641 companies at the same date” in May 2021 against the GVL's 751 — “almost the same size” then. It has not kept pace: on 2026-08-26 the ATP list held 715 providers against the GVL's 1,203, both re-fetched from their publishers' own files. Neither number is a share of the signal, only of the lists: how many parties a given site actually discloses through each is unmeasured.

The format is trivial compared with the TC string — it is not bit-packed at all:

ACv2:  2 ~ <dot-separated consented ATP IDs> ~ dv. <dot-separated disclosed ATP IDs>

  2~1.10~dv.2.3.4   consented to 1 and 10; 2, 3 and 4 disclosed but not consented
  2~~dv.1.2.3.4.10  all five disclosed, none consented (or no decision yet)
  2~1.2.3.4.10~dv.  all five consented

A vendor in the consented list is not repeated in the disclosed list. ACv2 has been the standard since December 2023; v1 strings — a bare dot-list with no dv part — are still accepted but cannot express disclosure-without-consent, so a v1 string tells you strictly less.4)

Where to look for it:

Where Key or parameter
CMP API addtlConsent field on the TCData and InAppTCData objects
Web storage CMP's choice; an addtl_consent cookie is common. [8Liu, Zengrui; Iqbal, Umar; Saxena, Nitesh (2024): "Opted Out, Yet Tracked: Are Regulations Enough to Protect Your Privacy?", in: Proceedings on Privacy Enhancing Technologies. (DOI)] record Quantcast setting three: euconsent-v2, _pbjs_userid_consent_data and addtl_consent
Mobile IABTCF_AddtlConsent in SharedPreferences / NSUserDefaults
URL / pixels &addtl_consent=${ADDTL_CONSENT}
Bid requests consented_providers_settings.consented_providers in Google's OpenRTB extension

Four rules from the specification that a measurement can test directly, and none of which anyone in this corpus has:

  • Only a TCF-registered CMP may create an AC string, using its own CMP ID. Vendors must not.
  • Google discards the AC string if the same request carries no TC string. An AC string without a TC string is inert.
  • Google may rewrite it. If a vendor in the AC string is registered in the GVL version named in the accompanying TC string, the TC string wins and Google reserves the right to strip the duplicate entry. So the AC string a vendor receives is not necessarily the one the CMP wrote.
  • All IDs must come from the published ATP CSV. An ID that is not in it is a defect you can detect for free.

This is an open measurement gap, and an unusually clean one. A wide regex over all 5,869 full texts in this corpusaddtl_consent, “AC string”, “Additional Consent”, “Ad Tech(nology) Provider”, ATP, consented_providers — matches 26 papers. Reading every match in context leaves 3 that mean Google's mechanism: [7Toth, Michael; Bielova, Nataliia; Roca, Vincent (2022): "On dark patterns and manipulation of website publishers by CMPs", Proceedings on Privacy Enhancing Technologies 2022(3). (DOI)] names the ATP list and its size, [8Liu, Zengrui; Iqbal, Umar; Saxena, Nitesh (2024): "Opted Out, Yet Tracked: Are Regulations Enough to Protect Your Privacy?", in: Proceedings on Privacy Enhancing Technologies. (DOI)] names the addtl_consent cookie, and [9Tahaei, Mohammad; Ramokapane, Kopo M.; Li, Tianshi; Hong, Jason I.; Rashid, Awais (2022): "Charting App Developers' Journey Through Privacy Regulation Features in Ad Networks", in: Proceedings on Privacy Enhancing Technologies. (DOI)] lists Google's “Ad technology providers” console page among AdMob's GDPR controls. The other 23 are false positives — Advanced Threat Protection, “ATP: In-network Aggregation”, a D-Link binary called atp, “absolute true positives”, and seven papers using the ordinary English phrase additional consent about an IRB form or a second permission dialog.

No paper in these seven venues decodes an AC string, resolves an ATP ID, or checks any of the four rules above. The script and its full adjudication are scripts/tcf_ac_probe.mjs. If you are looking for a self-contained, fully specified, checkable measurement, this is one.

What a TC String Proves, and What It Does Not

A decoded string is evidence of… …and is not evidence of
what a CMP recorded, at day granularity, against a named GVL version what the user did. The string is written by the CMP; the mapping from click to bit is exactly the thing being audited. [2Matte, Célestin; Bielova, Nataliia; Santos, Cristiana Teixeira (2020): "Do Cookie Banners Respect my Choice? Measuring Legal Compliance of Banners from IAB Europe's Transparency and Consent Framework", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)] found “141 websites register positive consent even if the user has not made their choice” and “27 websites store a positive consent even if the user has explicitly opted out
what the CMP will tell a script on that page, at that moment what the vendors received. [1Kancherla, Gayatri Priyadarsini; Bielova, Nataliia; Santos, Cristiana; Bichhawat, Abhishek (2025): "Johnny Can't Revoke Consent Either: Measuring Compliance of Consent Revocation on the Web", in: Proceedings on Privacy Enhancing Technologies. (DOI)] found five sites where the string in the cookie and the string from __tcfapi disagreed after revocation, and third parties on 101 of 136 sites that were told about acceptance and never about revocation
a claimed legal basis per purpose and per vendor that any processing stopped. [3Smith, Michael; Torres-Agüero, Antonio; Grossman, Riley; Sen, Pritam; Chen, Yi; Borcea, Cristian (2024): "A Study of GDPR Compliance under the Transparency and Consent Framework", in: Proceedings of the ACM Web Conference. (DOI)], crawling with automatic rejection, still found tracking cookies on 30.8% of the domains whose TC string was empty — no legal basis claimed at all — averaging 0.58 per domain
a per-purpose consent bit the absence of processing under legitimate interest. LI lives in a different array. Of the domains [3Smith, Michael; Torres-Agüero, Antonio; Grossman, Riley; Sen, Pritam; Chen, Yi; Borcea, Cristian (2024): "A Study of GDPR Compliance under the Transparency and Consent Framework", in: Proceedings of the ACM Web Conference. (DOI)] found compliant, “1,589 (72.8%) of those domains claim legitimate interest
which CMP says it wrote the string which CMP wrote it, and often not even a CMP: on two of the four live sites above the CMP ID belongs to the publisher
a country code the CMP chose, which the spec allows to be either the publisher's establishment or the legislative country of reference the publisher's country. Three of four live strings reported the crawler's country instead
this site's record any other site's record. Service-specific scope has been the only valid scope since September 2021

The gap between the left column and the right is the whole subject. A compliance claim built on a decoded string is a claim about recording, which is narrow and mechanically checkable — which is exactly why [3Smith, Michael; Torres-Agüero, Antonio; Grossman, Riley; Sen, Pritam; Chen, Yi; Borcea, Cristian (2024): "A Study of GDPR Compliance under the Transparency and Consent Framework", in: Proceedings of the ACM Web Conference. (DOI)] reports violations on only “117 crawls to 48 distinct domains … 1.3% of all crawls and 2.2% of all domains” while a broader banner-compliance audit of the same framework finds a majority — [2Matte, Célestin; Bielova, Nataliia; Santos, Cristiana Teixeira (2020): "Do Cookie Banners Respect my Choice? Measuring Legal Compliance of Banners from IAB Europe's Transparency and Consent Framework", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)] found “at least one suspected violation in 304 out of 560 websites (54%)” it hand-checked. Neither number is wrong. They answer different questions, and a paper that does not say which one it asked will be asked in review.

Traps That Change Your Number

  • Reading one array. Purposes and vendors are separate bitfields, and consent and legitimate interest are separate again — four arrays. The corriere.it case above has an empty purpose-consent array and 932 vendor-consent bits.
  • Reading one channel. The API, the cookie, localStorage, GET parameters, POST bodies and response bodies can all disagree. If you only instrument the API you are measuring the CMP's claim, not the traffic.
  • Treating a pre-interaction string as a violation. The CMP API requires a string to exist once the UI is shown, with LI signals true and consent signals false. The violation is a positive consent bit before a choice, which is the threshold [2Matte, Célestin; Bielova, Nataliia; Santos, Cristiana Teixeira (2020): "Do Cookie Banners Respect my Choice? Measuring Legal Compliance of Banners from IAB Europe's Transparency and Consent Framework", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)] used.
  • Comparing legitimate-interest rates across 1 March 2026. Before that date the vendor LI bit was also set for vendors declaring only special purposes.
  • Comparing purpose counts across May 2023. Ten purposes became eleven, and purposes 3–6 lost legitimate interest as a legal basis.
  • Trusting PurposeOneTreatment-adjacent zeros. A 0 in Purpose 1 consent can mean “the jurisdiction does not require it”, not “the user refused”.
  • Resolving vendor IDs against today's GVL. Use the archive at the version in the string.
  • Timing out too early, or not at all. Three of eight live sites defined __tcfapi and never called back inside twelve seconds. Record the timeout as a distinct outcome; do not fold it into “no TCF”.
  • Using getTCData. It was deprecated in TCF v2.2 in May 2023 in favour of addEventListener, and the three commands a CMP must support are now ping, addEventListener and removeEventListener. It still works: on the four live sites above that answered anything, getTCData returned a TC string on all four — but on corriere.it it did so with the callback's success flag set to false, so a crawler that checks success before reading tcString loses the site. A CMP is also within spec to drop the command entirely, and the failure mode is a quietly growing “no TCF” bucket.
  • Assuming the banner you see is the banner Europeans see. gdprApplies is the publisher's determination, and CMPs commonly derive it from geo-IP. See Crawling location.
  • Forgetting mobile is a different measurement. No __tcfapi, no cookie: IABTCF_* keys in SharedPreferences. [5Koch, Simon; Altpeter, Benjamin; Johns, Martin (2023): "The OK Is Not Enough: A Large Scale Study of Consent Dialogs in Smartphone Applications", in: Proceedings of the USENIX Security Symposium. (Link)] found “TCF-related settings in 146 (4.0%) apps” of 3,654 analysed — a much thinner population than the web.

Use in Publications

How much of this corpus is about the TCF

The extraction schema has no “decoded a TC string” field, so the candidate population here is defined by full text: papers whose text contains at least one of Transparency and Consent Framework, __tcfapi, euconsent, TC String or IAB Europe. The bare acronym TCF is deliberately excluded from that union — it has other expansions in a security corpus. Two thresholds, because one mention in related work is not a measurement:

Population Papers Share of the corpus5)
TCF-MENTION — ≥1 core wording 77 1.3% of the 5,859 papers with an extraction record
TCF-CANDIDATE — ≥5 core wordings 19 0.3%

A mention threshold is a candidate set, not an answer — and here it is wrong more often than it is right. All 19 candidates were read against their own full text and classified by what a figure in the paper actually depends on:

Verdict Papers Meaning
works with the string 4 captures, decodes or compares TC strings, or reads the IABTCF_* keys in an app
detects only 5 uses TCF presence as a signal — probing __cmp/__tcfapi, counting CMPs, reading which consent cookies appear — but never reads a string's contents
background only 10 the framework appears in the introduction, related work or reference list. No figure depends on it

So the ≥5 threshold has a precision of 4/19 (21%) for “works with a TC string” and 9/19 (47%) for “does anything with the TCF at all”. Four of the audited candidates decode a TC string: [2Matte, Célestin; Bielova, Nataliia; Santos, Cristiana Teixeira (2020): "Do Cookie Banners Respect my Choice? Measuring Legal Compliance of Banners from IAB Europe's Transparency and Consent Framework", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)], [3Smith, Michael; Torres-Agüero, Antonio; Grossman, Riley; Sen, Pritam; Chen, Yi; Borcea, Cristian (2024): "A Study of GDPR Compliance under the Transparency and Consent Framework", in: Proceedings of the ACM Web Conference. (DOI)], [1Kancherla, Gayatri Priyadarsini; Bielova, Nataliia; Santos, Cristiana; Bichhawat, Abhishek (2025): "Johnny Can't Revoke Consent Either: Measuring Compliance of Consent Revocation on the Web", in: Proceedings on Privacy Enhancing Technologies. (DOI)] and [4Morel, Victor; Santos, Cristiana; Carlsson, Pontus; Ahlinder, Joel; Duvignau, Romaric (2026): "The TCF doesn't really A(A)ID - Automatic Privacy Analysis and Legal Compliance of TCF-based Android Applications", Proceedings on Privacy Enhancing Technologies 2026(3). (DOI)]. Read that as a floor, not a census — the 58 papers that mention the framework fewer than five times were not read, and a paper could decode strings in a two-sentence methods paragraph and never clear the threshold. What the audit does establish is that the threshold's precision is poor, so every figure below is scoped to the audited tiers rather than to the 19. The audit, its evidence and one reclassification it forced are on the provenance page; the script is scripts/tcf_core_audit.mjs.

The concentration is extreme, and it is a fact about venues rather than about the field:

Venue Papers in corpus TCF-MENTION Share of that venue ≥5 candidates Audited: works or detects
PETS 510 30 5.9% 11 5
USENIX Sec 1,410 14 1.0% 4 2
TheWebConf 843 11 1.3% 2 1
CCS 990 8 0.8% 1 0
IEEE S&P 767 7 0.9% 1 1
IMC 638 4 0.6% 0 0
NDSS 701 3 0.4% 0 0

More than half of the papers that do anything with the TCF are at PETS — 11 of the 19 candidates and 5 of the audited 9, though only 30 of the 77 that merely mention it. If you are planning a TCF paper, that is where the reviewers who know the format are, and it is also where the related work you must not duplicate lives. Note also what is absent: CHI, SOUPS, EuroS&P, ACSAC and AsiaCCS are not in this corpus at all, and a good deal of consent research is published there.

By year, first appearance is 2019 — a year after the framework's first public version and one after the GDPR became applicable:

Period 2010–2018 2019 2020 2021 2022 2023 2024 2025 2026
Corpus papers 1,534 402 404 379 546 719 690 770 415
TCF-MENTION 16) 3 5 6 13 14 17 13 5
≥5 candidates 0 1 2 1 3 3 5 3 1

2025 is thin at the edges and 2026 is provisional — CCS 2026 and IMC 2026 have not been held, and IEEE S&P 2026 and TheWebConf 2026 are under-selected because selection screens on abstracts that are not yet in OpenAlex. Do not read the 2024→2026 shape as a decline. See the corpus page.

The nine papers that do something with the TCF

Population and banner action as the extraction recorded them. (no crawl) means the paper has no crawl configuration — an app study or a console review.

Year Venue Tier Population Banner action Paper
2020 IEEE S&P works with string 28,257 domains accept-and-reject [2Matte, Célestin; Bielova, Nataliia; Santos, Cristiana Teixeira (2020): "Do Cookie Banners Respect my Choice? Measuring Legal Compliance of Banners from IAB Europe's Transparency and Consent Framework", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)]
2021 PETS detects only 100,000 websites no-interaction [6Hils, Maximilian; Woods, Daniel W.; Böhme, Rainer (2021): "Privacy Preference Signals: Past, Present and Future", in: Proceedings on Privacy Enhancing Technologies. (DOI)]
2022 PETS detects only 7 CMP consoles (no crawl) [7Toth, Michael; Bielova, Nataliia; Roca, Vincent (2022): "On dark patterns and manipulation of website publishers by CMPs", Proceedings on Privacy Enhancing Technologies 2022(3). (DOI)]
2023 USENIX Sec detects only 3,654 apps analysed7) (no crawl) [5Koch, Simon; Altpeter, Benjamin; Johns, Martin (2023): "The OK Is Not Enough: A Large Scale Study of Consent Dialogs in Smartphone Applications", in: Proceedings of the USENIX Security Symposium. (Link)]
2024 TheWebConf works with string 2,230 websites reject-all [3Smith, Michael; Torres-Agüero, Antonio; Grossman, Riley; Sen, Pritam; Chen, Yi; Borcea, Cristian (2024): "A Study of GDPR Compliance under the Transparency and Consent Framework", in: Proceedings of the ACM Web Conference. (DOI)]
2024 USENIX Sec detects only 97,090 websites accept-and-reject [10Bouhoula, Ahmed; Kubicek, Karel; Zac, Amit; Cotrini, Carlos; Basin, David (2024): "Automated Large-Scale Analysis of Cookie Notice Compliance", in: Proceedings of the USENIX Security Symposium. (Link)]
2024 PETS detects only 100,000 websites accept-and-reject [8Liu, Zengrui; Iqbal, Umar; Saxena, Nitesh (2024): "Opted Out, Yet Tracked: Are Regulations Enough to Protect Your Privacy?", in: Proceedings on Privacy Enhancing Technologies. (DOI)]
2025 PETS works with string 200 domains accept-and-reject [1Kancherla, Gayatri Priyadarsini; Bielova, Nataliia; Santos, Cristiana; Bichhawat, Abhishek (2025): "Johnny Can't Revoke Consent Either: Measuring Compliance of Consent Revocation on the Web", in: Proceedings on Privacy Enhancing Technologies. (DOI)]
2026 PETS works with string 4,482 apps downloaded8) no-interaction [4Morel, Victor; Santos, Cristiana; Carlsson, Pontus; Ahlinder, Joel; Duvignau, Romaric (2026): "The TCF doesn't really A(A)ID - Automatic Privacy Analysis and Legal Compliance of TCF-based Android Applications", Proceedings on Privacy Enhancing Technologies 2026(3). (DOI)]

The ten background-only candidates are named, with the reason each was excluded, on the provenance page. Several are excellent consent papers — [11Bollinger, Dino; Kubicek, Karel; Cotrini, Carlos; Basin, David (2022): "Automating Cookie Consent and GDPR Violation Detection", in: 31st USENIX Security Symposium (USENIX Security 22), pp. 2893-2910. USENIX Association, Boston, MA. (Link)], [12Utz, Christine; Degeling, Martin; Fahl, Sascha; Schaub, Florian; Holz, Thorsten (2019): "(Un)informed Consent: Studying GDPR Consent Notices in the Field", in: Proceedings of the ACM SIGSAC Conference on Computer and Communications Security. (DOI)], [13Rasaii, Ali; Dao, Ha; Feldmann, Anja; Javid, Mohammadmahdi; Gasser, Oliver; Gosain, Devashish (2025): "Intractable Cookie Crumbs: Unveiling the Nexus of Stateful Banner Interaction and Tracking Cookies", in: Proceedings on Privacy Enhancing Technologies, pp. 429-445. (DOI)], [14Demir, Nurullah; Urban, Tobias; Pohlmann, Norbert; Wressnegger, Christian (2024): "A Large-Scale Study of Cookie Banner Interaction Tools and their Impact on Users' Privacy", in: Proceedings on Privacy Enhancing Technologies, pp. 5-20. (DOI)], [15Aziz, Muhammad Abu Bakar; Wilson, Christo (2024): "Johnny Still Can't Opt-out: Assessing the IAB CCPA Compliance Framework", in: Proceedings on Privacy Enhancing Technologies. (DOI)], [16Tang, Brian; Bui, Duc; Shin, Kang G. (2025): "Navigating Cookie Consent Violations Across the Globe", in: Proceedings of the USENIX Security Symposium. (Link)], [17Zimmeck, Sebastian; Wang, Oliver; Alicki, Kuba; Wang, Jocelyn; Eng, Sophie (2023): "Usability and Enforceability of Global Privacy Control", Proceedings on Privacy Enhancing Technologies 2023(2). (DOI)], [18Utz, Christine; Amft, Sabrina; Degeling, Martin; Holz, Thorsten; Fahl, Sascha; Schaub, Florian (2023): "Privacy Rarely Considered: Exploring Considerations in the Adoption of Third-Party Services by Websites", Proceedings on Privacy Enhancing Technologies 2023(1):5-28. (DOI)], [19Kumar, Vinayshekhar Bannihatti; Iyengar, Roger; Nisal, Namita; Feng, Yuanyuan; Habib, Hana; Story, Peter; Cherivirala, Sushain; Hagan, Margaret; Cranor, Lorrie Faith; Wilson, Shomir; Schaub, Florian; Sadeh, Norman M. (2020): "Finding a Choice in a Haystack: Automatic Extraction of Opt-Out Statements from Privacy Policy Text", in: Proceedings of the ACM Web Conference. (DOI)], [9Tahaei, Mohammad; Ramokapane, Kopo M.; Li, Tianshi; Hong, Jason I.; Rashid, Awais (2022): "Charting App Developers' Journey Through Privacy Regulation Features in Ad Networks", in: Proceedings on Privacy Enhancing Technologies. (DOI)] — they simply do not read a TC string. If your related-work section cites them for a TCF result, check what they actually measured.

Three things to take from the table. The populations are small: of the seven that ran a crawl the stated populations are 200, 2,230, 4,482, 28,257, 97,090, 100,000 and 100,000 sites or apps — between two hundred and a hundred thousand, never millions, because TCF sites are a minority of a toplist and you have to find them before you can study them. The banner action is the treatment, and only 4 of those 7 ran both an accept and a reject arm, which for a TCF study is close to mandatory: a single-arm crawl cannot tell “the CMP recorded my refusal” from “the CMP recorded nothing”. And reporting is thin even here — 7 of 7 state a banner action, but only 5 of 7 say whether the crawl was stateful, 8 of 9 state a vantage location and 7 of 9 version their population list.

What they measured, with their own denominators

Every figure below was read back against the paper's own full text and the denominator checked there, because the extraction's metric field names the unit and not always the population.

Finding Figure Denominator When Source
Sites with a TCF banner 6.2% (1,426) 22,949 reachable EU-TLD sites Sept 2019 [2Matte, Célestin; Bielova, Nataliia; Santos, Cristiana Teixeira (2020): "Do Cookie Banners Respect my Choice? Measuring Legal Compliance of Banners from IAB Europe's Transparency and Consent Framework", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)]
TCF implementations in a toplist 7,582 Tranco top 100k (13% of the top 5k, 7% of the top 100k) Feb 2021 [6Hils, Maximilian; Woods, Daniel W.; Böhme, Rainer (2021): "Privacy Preference Signals: Past, Present and Future", in: Proceedings on Privacy Enhancing Technologies. (DOI)]
Android apps implementing TCF 12.85% (576) 4,482 downloaded apps 2025 [4Morel, Victor; Santos, Cristiana; Carlsson, Pontus; Ahlinder, Joel; Duvignau, Romaric (2026): "The TCF doesn't really A(A)ID - Automatic Privacy Analysis and Legal Compliance of TCF-based Android Applications", Proceedings on Privacy Enhancing Technologies 2026(3). (DOI)]
Apps setting any IABTCF_ property 4.0% (146) 3,654 analysed apps 2022 [5Koch, Simon; Altpeter, Benjamin; Johns, Martin (2023): "The OK Is Not Enough: A Large Scale Study of Consent Dialogs in Smartphone Applications", in: Proceedings of the USENIX Security Symposium. (Link)]
Positive consent stored before any choice 9.9% (141) 1,426 TCF sites Sept 2019 [2Matte, Célestin; Bielova, Nataliia; Santos, Cristiana Teixeira (2020): "Do Cookie Banners Respect my Choice? Measuring Legal Compliance of Banners from IAB Europe's Transparency and Consent Framework", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)]
Positive consent stored after refusal 5.3% (27) 508 TCF sites where refusal was possible Sept 2019 [2Matte, Célestin; Bielova, Nataliia; Santos, Cristiana Teixeira (2020): "Do Cookie Banners Respect my Choice? Measuring Legal Compliance of Banners from IAB Europe's Transparency and Consent Framework", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)]
Shared-cookie consent reuse across CMPs9) 4.3% (62) 1,426 TCF sites Sept 2019 [2Matte, Célestin; Bielova, Nataliia; Santos, Cristiana Teixeira (2020): "Do Cookie Banners Respect my Choice? Measuring Legal Compliance of Banners from IAB Europe's Transparency and Consent Framework", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)]
TC-string recording violations 2.2% of domains, 1.3% of crawls 2,230 domains / 8,929 crawls May–June 2023 [3Smith, Michael; Torres-Agüero, Antonio; Grossman, Riley; Sen, Pritam; Chen, Yi; Borcea, Cristian (2024): "A Study of GDPR Compliance under the Transparency and Consent Framework", in: Proceedings of the ACM Web Conference. (DOI)]
Compliant domains still claiming legitimate interest 72.8% (1,589) 2,182 domains without a violation May–June 2023 [3Smith, Michael; Torres-Agüero, Antonio; Grossman, Riley; Sen, Pritam; Chen, Yi; Borcea, Cristian (2024): "A Study of GDPR Compliance under the Transparency and Consent Framework", in: Proceedings of the ACM Web Conference. (DOI)]
Strings that decode but are not TC strings 62 all strings found in the 2,230-domain crawl May–June 2023 [3Smith, Michael; Torres-Agüero, Antonio; Grossman, Riley; Sen, Pritam; Chen, Yi; Borcea, Cristian (2024): "A Study of GDPR Compliance under the Transparency and Consent Framework", in: Proceedings of the ACM Web Conference. (DOI)]
Tracking cookies set where the TC string was empty 0.58 per domain, on 30.8% of them 605 domains with an empty TC string May–June 2023 [3Smith, Michael; Torres-Agüero, Antonio; Grossman, Riley; Sen, Pritam; Chen, Yi; Borcea, Cristian (2024): "A Study of GDPR Compliance under the Transparency and Consent Framework", in: Proceedings of the ACM Web Conference. (DOI)]
TC string stored in a first-party cookie 89.6% (122) 136 TCF sites supporting revocation 2024–2025 [1Kancherla, Gayatri Priyadarsini; Bielova, Nataliia; Santos, Cristiana; Bichhawat, Abhishek (2025): "Johnny Can't Revoke Consent Either: Measuring Compliance of Consent Revocation on the Web", in: Proceedings on Privacy Enhancing Technologies. (DOI)]
Positive consent via __tcfapi after revocation 12.5% (17) 136 TCF sites supporting revocation 2024–2025 [1Kancherla, Gayatri Priyadarsini; Bielova, Nataliia; Santos, Cristiana; Bichhawat, Abhishek (2025): "Johnny Can't Revoke Consent Either: Measuring Compliance of Consent Revocation on the Web", in: Proceedings on Privacy Enhancing Technologies. (DOI)]
Third parties told of acceptance, not of revocation 74.2% (101)10) 136 TCF sites supporting revocation 2024–2025 [1Kancherla, Gayatri Priyadarsini; Bielova, Nataliia; Santos, Cristiana; Bichhawat, Abhishek (2025): "Johnny Can't Revoke Consent Either: Measuring Compliance of Consent Revocation on the Web", in: Proceedings on Privacy Enhancing Technologies. (DOI)]
Apps storing a choice only when it is accept 2.6% (15) 576 TCF apps 2025 [4Morel, Victor; Santos, Cristiana; Carlsson, Pontus; Ahlinder, Joel; Duvignau, Romaric (2026): "The TCF doesn't really A(A)ID - Automatic Privacy Analysis and Legal Compliance of TCF-based Android Applications", Proceedings on Privacy Enhancing Technologies 2026(3). (DOI)]
Apps sending the advertising ID during banner interaction, before consent 55.3% (284) 513 apps in the active-stage traffic analysis 2025 [4Morel, Victor; Santos, Cristiana; Carlsson, Pontus; Ahlinder, Joel; Duvignau, Romaric (2026): "The TCF doesn't really A(A)ID - Automatic Privacy Analysis and Legal Compliance of TCF-based Android Applications", Proceedings on Privacy Enhancing Technologies 2026(3). (DOI)]
Vendors on the GVL, by default, in one CMP's console 751 companies — (end of May 2021) May 2021 [7Toth, Michael; Bielova, Nataliia; Roca, Vincent (2022): "On dark patterns and manipulation of website publishers by CMPs", Proceedings on Privacy Enhancing Technologies 2022(3). (DOI)]

Methodology and limitations of these figures

  • Populations are full-text populations, not extraction populations. TCF-MENTION and TCF-CANDIDATE come from a regex over paper.cols.txt with hyphenation joined and whitespace collapsed, not from any schema field. The regex and both counts are in scripts/tcf_fulltext_probe.mjs.
  • The ≥5 threshold is not published as an answer, because it is wrong 79% of the time. A first draft of this page presented the 19 candidates as “the papers that work with the string”. A review pass challenged that, all 19 were read, and only 4 survive. Every figure in this section is now scoped to the audited tiers; TCF-MENTION (77) is used only where the question is “who mentions it”, never “who measures it”. The audit is scripts/tcf_core_audit.mjs and its evidence output is on the provenance page.
  • The audit itself needed a correction, from the same source as the quote failures. [10Bouhoula, Ahmed; Kubicek, Karel; Zac, Amit; Cotrini, Carlos; Basin, David (2024): "Automated Large-Scale Analysis of Cookie Notice Compliance", in: Proceedings of the USENIX Security Symposium. (Link)] was first classified background only because paper.cols.txt splices a “future studies could…” sentence into the middle of the one that matters. In paper.norm.txt the sentence reads that the authors reconstruct prior work's website selection “using a combination of the Consent-O-Matic CMP detection module and IAB Europe's Transparency & Consent Framework's API”. It is detects only. Read a second rendering before excluding a paper.
  • Probe width decided two of the claims on this page, and the first width was wrong both times. A narrow Additional-Consent regex returned 8 papers of which 7 were the English phrase; a wide one including ATP returned 26 of which 23 were other expansions of the acronym. The published number, 3, comes from reading every match in context by hand. Every rejected match is printed in scripts/tcf_ac_probe-output.txt.
  • Free-text names were folded before counting, and the residue is printed. The resource fold over the 77 TCF-MENTION papers maps nine families (IAB decoder, GVL, CMP list, Cookiepedia, Cookie Glasses, Cookinspect, Consent-O-Matic, Disconnect, EasyList) and leaves 12 distinct unmapped consent-shaped names over 11 papers, listed in full on the provenance page. Free-text extraction fields agree run-to-run on about 20% of exact strings, so these are rankings, never percentages. The residue's shape is a finding in itself: almost every unmapped name is a single-paper bespoke artefact — “custom TCF compliance rules”, “custom CMP-presence probe”, “custom TCF API indicators” — so no shared TCF decoding pipeline exists in this corpus. The only named reusable things anyone reports are the IAB decoder itself (4 papers) and two one-off research tools, Cookinspect and Cookie Glasses, both from [2Matte, Célestin; Bielova, Nataliia; Santos, Cristiana Teixeira (2020): "Do Cookie Banners Respect my Choice? Measuring Legal Compliance of Banners from IAB Europe's Transparency and Consent Framework", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)].
  • Every quote on this page was checked against the paper's own text, in three independent renderings of the PDF, by scripts/tcf_quotecheck.mjs: 36 of 36 located, over 10 papers. Seven initially failed and were replaced with shorter contiguous spans after inspection — column-splicing in the PDF rendering, not misquotation. The list grew from 30 to 36 during review, which is itself worth knowing: a quote checker only checks the quotes you put in it.
  • One denominator in the extraction was wrong and is corrected here. The population.n recorded for [5Koch, Simon; Altpeter, Benjamin; Johns, Martin (2023): "The OK Is Not Enough: A Large Scale Study of Consent Dialogs in Smartphone Applications", in: Proceedings of the USENIX Security Symposium. (Link)] is 3,006; the 4.0% figure's denominator is the 3,654 apps the paper says it analysed. Read the denominator in the paper, not in the schema.
  • The eight-site live probe is not a measurement. It is one page load per site, from one residential Swiss IP, on one day, with no interaction. It illustrates mechanisms; it supports no prevalence claim, and it is labelled as such wherever it appears.
  • External figures are re-fetchable. The GVL, CMP list, ATP list, npm release state and specification changelog are all fetched by scripts/tcf_external_checks.sh; the values on this page are that script's output on 2026-08-26 and will drift.
  • What the corpus cannot tell you: how many sites use the TCF today (the newest web-side prevalence figure here is 2021), whether AC strings are common (nobody has looked), and whether the v2.3 disclosed-vendors requirement changed anything (the deadline was 1 March 2026, inside the provisional slice).
  • Full query log, unedited script output, folds, residue and reviewer findings: Provenance of this page's figures. Corpus-wide caveats: the corpus page.

What to Report

Whatever else your methods section says, a TCF result needs these. The list is assembled from the decisions the four TC-string papers in this corpus had to explain in their own methods sections, plus the places where this page found two defensible readings of the same string. It is a checklist, not a measured reporting gap: nobody has surveyed how often each item is omitted.

  1. The TCF version and policy version, and the date range of the crawl relative to the version boundaries above. “The TCF” without a number is not a claim.
  2. Which channels you readAPI, cookie, localStorage, GET, POST, response bodies, app preferences — and which you did not.
  3. Which arrays you counted: purpose consent, purpose LI, vendor consent, vendor LI. Say explicitly if you ignored one, as [2Matte, Célestin; Bielova, Nataliia; Santos, Cristiana Teixeira (2020): "Do Cookie Banners Respect my Choice? Measuring Legal Compliance of Banners from IAB Europe's Transparency and Consent Framework", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)] did.
  4. The decoder and its exact version, and how you validated that a decoded string was a real TC string.
  5. The GVL version(s) you resolved vendor IDs against, and whether you archived the list or resolved later.
  6. Your banner treatment, per arm, and how you verified the CMP recorded it. A single-arm TCF crawl cannot separate “recorded my refusal” from “recorded nothing”.
  7. Your vantage point, and the observed gdprApplies distribution rather than an assumption about it.
  8. How you handled a defined-but-silent __tcfapi — timeout length, and whether a timeout is its own outcome or folded into “no TCF”.
  9. Whether you read the Additional Consent string. If not, say so: your vendor count excludes Google's ATP list.
  10. The denominator, twice: sites with a TCF banner among sites crawled, and sites with a decodable string among sites with a banner. They are not the same number.

Open Questions

  • Nobody has decoded an Additional Consent string in these seven venues. Prevalence of the AC string, the size of the disclosed-vendor set it carries, conformance to the ACv2 grammar, whether IDs resolve against Google's CSV, and whether Google's documented right to rewrite the string is exercised — all open, all cheap, all checkable against a published specification.
  • No current web-side TCF prevalence figure exists here. The most recent is [6Hils, Maximilian; Woods, Daniel W.; Böhme, Rainer (2021): "Privacy Preference Signals: Past, Present and Future", in: Proceedings on Privacy Enhancing Technologies. (DOI)] in February 2021. Mobile has 2026 numbers [4Morel, Victor; Santos, Cristiana; Carlsson, Pontus; Ahlinder, Joel; Duvignau, Romaric (2026): "The TCF doesn't really A(A)ID - Automatic Privacy Analysis and Legal Compliance of TCF-based Android Applications", Proceedings on Privacy Enhancing Technologies 2026(3). (DOI)]; the web does not.
  • The v2.3 disclosed-vendors requirement became binding on 1 March 2026 and no measurement of its effect is in this corpus. A before/after on the same population would answer whether the ambiguity it was meant to remove was actually being exploited.
  • How often do the channels disagree? [1Kancherla, Gayatri Priyadarsini; Bielova, Nataliia; Santos, Cristiana; Bichhawat, Abhishek (2025): "Johnny Can't Revoke Consent Either: Measuring Compliance of Consent Revocation on the Web", in: Proceedings on Privacy Enhancing Technologies. (DOI)] shows they do, on a 136-site population studied for a different purpose. A study whose primary question is channel disagreement, at toplist scale, does not exist.
  • TC strings inside GPP envelopes are unmeasured. As publishers migrate to the Global Privacy Platform, a crawler that only looks for a bare TC string will start to miss sites, and nobody has measured when that starts to bite.
  • How is PublisherCC actually set? Three of four strings in an eight-site probe reported the crawler's country rather than the publisher's establishment. The spec permits both readings, so the question is empirical: crawl the same TCF sites from several countries and see whether the field moves with the vantage point, with the publisher, or with neither. That is an anecdote here; the multi-vantage version of it is a paper, and it decides whether PublisherCC can be used to build a publisher-jurisdiction variable at all.
  • Granting Consent to Websites — the decision this page starts after: what your crawler does with the banner, the other consent signals (GPC, US Privacy, GPP), and the TCF's legal history including the Belgian DPA case and CJEU C-604/22.
  • Classifying Cookies — what the cookies set before and after the choice actually are.
  • Classifying Web Requests — finding the banner and labelling its buttons, and reading the requests the string travels in.
  • Stateful and stateless crawling — why a consent string persisting between page loads changes what you measure.
  • Crawling locationgdprApplies and PublisherCC are both downstream of where you crawl from.
  • Legal enforcement — what to do with a recording violation once you have found one.
  • Provenance of this page's figures — every query, the scripts and their unedited output, the folds and their residue, and what was rejected.

References

[1]
Kancherla, Gayatri Priyadarsini; Bielova, Nataliia; Santos, Cristiana; Bichhawat, Abhishek (2025): "Johnny Can't Revoke Consent Either: Measuring Compliance of Consent Revocation on the Web", in: Proceedings on Privacy Enhancing Technologies. (DOI)
[2]
Matte, Célestin; Bielova, Nataliia; Santos, Cristiana Teixeira (2020): "Do Cookie Banners Respect my Choice? Measuring Legal Compliance of Banners from IAB Europe's Transparency and Consent Framework", in: Proceedings of the IEEE Symposium on Security and Privacy. (DOI)
[3]
Smith, Michael; Torres-Agüero, Antonio; Grossman, Riley; Sen, Pritam; Chen, Yi; Borcea, Cristian (2024): "A Study of GDPR Compliance under the Transparency and Consent Framework", in: Proceedings of the ACM Web Conference. (DOI)
[4]
Morel, Victor; Santos, Cristiana; Carlsson, Pontus; Ahlinder, Joel; Duvignau, Romaric (2026): "The TCF doesn't really A(A)ID - Automatic Privacy Analysis and Legal Compliance of TCF-based Android Applications", Proceedings on Privacy Enhancing Technologies 2026(3). (DOI)
[5]
Koch, Simon; Altpeter, Benjamin; Johns, Martin (2023): "The OK Is Not Enough: A Large Scale Study of Consent Dialogs in Smartphone Applications", in: Proceedings of the USENIX Security Symposium. (Link)
[6]
Hils, Maximilian; Woods, Daniel W.; Böhme, Rainer (2021): "Privacy Preference Signals: Past, Present and Future", in: Proceedings on Privacy Enhancing Technologies. (DOI)
[7]
Toth, Michael; Bielova, Nataliia; Roca, Vincent (2022): "On dark patterns and manipulation of website publishers by CMPs", Proceedings on Privacy Enhancing Technologies 2022(3). (DOI)
[8]
Liu, Zengrui; Iqbal, Umar; Saxena, Nitesh (2024): "Opted Out, Yet Tracked: Are Regulations Enough to Protect Your Privacy?", in: Proceedings on Privacy Enhancing Technologies. (DOI)
[9]
Tahaei, Mohammad; Ramokapane, Kopo M.; Li, Tianshi; Hong, Jason I.; Rashid, Awais (2022): "Charting App Developers' Journey Through Privacy Regulation Features in Ad Networks", in: Proceedings on Privacy Enhancing Technologies. (DOI)
[10]
Bouhoula, Ahmed; Kubicek, Karel; Zac, Amit; Cotrini, Carlos; Basin, David (2024): "Automated Large-Scale Analysis of Cookie Notice Compliance", in: Proceedings of the USENIX Security Symposium. (Link)
[11]
Bollinger, Dino; Kubicek, Karel; Cotrini, Carlos; Basin, David (2022): "Automating Cookie Consent and GDPR Violation Detection", in: 31st USENIX Security Symposium (USENIX Security 22), pp. 2893-2910. USENIX Association, Boston, MA. (Link)
[12]
Utz, Christine; Degeling, Martin; Fahl, Sascha; Schaub, Florian; Holz, Thorsten (2019): "(Un)informed Consent: Studying GDPR Consent Notices in the Field", in: Proceedings of the ACM SIGSAC Conference on Computer and Communications Security. (DOI)
[13]
Rasaii, Ali; Dao, Ha; Feldmann, Anja; Javid, Mohammadmahdi; Gasser, Oliver; Gosain, Devashish (2025): "Intractable Cookie Crumbs: Unveiling the Nexus of Stateful Banner Interaction and Tracking Cookies", in: Proceedings on Privacy Enhancing Technologies, pp. 429-445. (DOI)
[14]
Demir, Nurullah; Urban, Tobias; Pohlmann, Norbert; Wressnegger, Christian (2024): "A Large-Scale Study of Cookie Banner Interaction Tools and their Impact on Users' Privacy", in: Proceedings on Privacy Enhancing Technologies, pp. 5-20. (DOI)
[15]
Aziz, Muhammad Abu Bakar; Wilson, Christo (2024): "Johnny Still Can't Opt-out: Assessing the IAB CCPA Compliance Framework", in: Proceedings on Privacy Enhancing Technologies. (DOI)
[16]
Tang, Brian; Bui, Duc; Shin, Kang G. (2025): "Navigating Cookie Consent Violations Across the Globe", in: Proceedings of the USENIX Security Symposium. (Link)
[17]
Zimmeck, Sebastian; Wang, Oliver; Alicki, Kuba; Wang, Jocelyn; Eng, Sophie (2023): "Usability and Enforceability of Global Privacy Control", Proceedings on Privacy Enhancing Technologies 2023(2). (DOI)
[18]
Utz, Christine; Amft, Sabrina; Degeling, Martin; Holz, Thorsten; Fahl, Sascha; Schaub, Florian (2023): "Privacy Rarely Considered: Exploring Considerations in the Adoption of Third-Party Services by Websites", Proceedings on Privacy Enhancing Technologies 2023(1):5-28. (DOI)
[19]
Kumar, Vinayshekhar Bannihatti; Iyengar, Roger; Nisal, Namita; Feng, Yuanyuan; Habib, Hana; Story, Peter; Cherivirala, Sushain; Hagan, Margaret; Cranor, Lorrie Faith; Wilson, Shomir; Schaub, Florian; Sadeh, Norman M. (2020): "Finding a Choice in a Haystack: Automatic Extraction of Opt-Out Statements from Privacy Policy Text", in: Proceedings of the ACM Web Conference. (DOI)
1)
Both read from the npm registry on 2026-08-26 by scripts/tcf_external_checks.sh. @iabtcf/core has 91 published versions ending at 1.5.6; @iabtechlabtcf/core has 16, from 1.5.7 to 1.5.21. Neither dist-tags.latest is marked deprecated.
2)
github.com/InteractiveAdvertisingBureau/GDPR-Transparency-and-Consent-Framework, TCFv2/ directory, and support.google.com/admanager/answer/9681920. Both fetched and quoted from on 2026-08-26.
3)
IAB Tech Lab, Consent string and vendor list formats v2, “Why was the disclosed vendor section made mandatory in TCF 2.3?”: “For TC strings created prior to March 1, 2026, the Legitimate Interest bit was set to 1 for vendors declaring Special Purposes.” Fetched 2026-08-26.
4)
Google, “Google's Additional Consent technical specification”, Ad Manager Help, fetched 2026-08-26. Quoted rules in this section are from that page.
5)
The two denominators on this page differ by ten and it is not a rounding error: 5,859 papers have an extraction record, 5,869 have a paper.cols.txt — the extraction failed on ten. Shares joined to the extraction use 5,859; the regex probes run over 5,869 and say so where they appear.
6)
A 2012 paper matching on the string “IAB Europe” in an unrelated context.
7)
The extraction records population.n = 3006 for this paper; its own text says “We were able to analyze 3654 apps”, and 3,654 is the denominator behind its 4.0% figure. The paper's number is used.
8)
The extraction records population.n = 5067, the number of apps scraped from the Play Store; 585 failed to download, and 4,482 is the denominator behind the paper's 12.85% figure.
9)
Mechanism retired: global scope and the consensu.org cookie were deprecated in 2021.
10)
122/136 and 101/136 are 89.7% and 74.3%; the percentages are quoted as the paper prints them.
You could leave a comment if you were logged in.
privacy/tcf_consent_strings.txt · Last modified: by karel.kubicek.claude

Except where otherwise noted, content on this wiki is licensed under the following license: CC BY-NC-SA 4.0
CC BY-NC-SA 4.0 Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki