IAB TCF v2.2, explained for engineers
- Byline
- + Byline
- Originally published at
- + Originally published at
- Share image
- + Share image
The IAB Europe Transparency & Consent Framework (TCF) is the standard that lets a website, its consent banner and the advertising vendors it works with speak the same language about consent. If you run programmatic advertising in Europe, the ad-tech vendors in your stack almost certainly expect a TCF signal, and without one many will simply decline to serve personalised ads. This is the engineer's-eye view of what that machinery is.
At the centre are three moving parts: a Consent Management Platform (CMP), registered with IAB Europe and issued a numeric CMP ID; the Global Vendor List (GVL), a JSON document enumerating every registered vendor, the purposes they declare and the features they use; and the TC string, a compact encoded record of one user's choices. The CMP's job is to present the GVL to the user and produce a valid TC string from their answers.
The GVL is versioned and fetched from IAB's CDN. It defines eleven standard Purposes — such as “Store and/or access information on a device” (Purpose 1) and “Create profiles for personalised advertising” (Purpose 3) — along with Special Purposes, Features and Special Features. Each vendor entry lists which purposes it relies on and whether it claims consent or legitimate interest for each. A CMP must render these in language a user can understand, which is exactly what v2.2 tightened.
Version 2.2, which became mandatory in 2023, made several concrete changes. Legitimate interest is no longer an allowed legal basis for advertising and content-personalisation purposes (Purposes 3 to 6), so those are consent-only. Banners must state how many vendors are seeking data, remove any “legitimate interest” toggles for those advertising purposes, and show standardised, plain-language names and illustrations for each purpose. Vendors must also declare data-retention periods and the categories of data they collect.
The TC string itself is a base64url-encoded, bit-packed structure. It records the CMP ID and version, the GVL version, timestamps, the purposes the user consented to, the purposes for which legitimate interest was established, per-vendor consent and legitimate-interest bits, special-feature opt-ins, and any publisher restrictions. Because vendor lists are large, the vendor sections can be encoded as ranges or bitfields, whichever is smaller. It is typically stored in the euconsent-v2 cookie so it persists across pages.
Vendors read the string through a single global function, __tcfapi. Your CMP defines it, and callers invoke __tcfapi('getTCData', 2, callback) to get the decoded consent, or 'addEventListener' to be notified as the user interacts. A 'ping' command reports whether the CMP is loaded and whether a UI is showing. The second argument, 2, is the TCF API version.
Because ad tags frequently run inside iframes, the framework defines a cross-frame transport. The CMP creates a __tcfapiLocator iframe so that code in other frames can find it, and messages are exchanged via postMessage using a __tcfapiCall envelope. A vendor SDK that cannot reach __tcfapi directly falls back to this postMessage channel, and the CMP replies the same way.
Timing is strict. The __tcfapi function — at minimum a stub that queues calls — must exist before any vendor script runs, so early callers are queued rather than lost. The CMP answers a getTCData call with a cmpStatus and an eventStatus: tcloaded while it is still resolving, cmpuishown while the UI is up, and useractioncomplete once the user has chosen. Vendors are expected to wait for a complete status before acting on the string.
Publisher restrictions are the lever the site itself holds. A publisher can override what a vendor may do — for example, forbidding a vendor from relying on legitimate interest for a purpose, or disallowing a purpose entirely — and these restrictions are encoded into the TC string so downstream vendors must respect them. This is how a site tightens the default vendor declarations rather than accepting them wholesale.
TCF does not stand alone. For US traffic the parallel signal is GPP, the Global Privacy Platform, which can carry a TCF EU section alongside US state sections; and the wider ecosystem defines an Additional Consent string for vendors not yet on the GVL. A complete banner has to emit the right combination for the visitor rather than treating TCF as the whole picture.
Cookie Munch implements the TCF v2.2 CMP API. It fetches the current GVL from the v3 vendor-list endpoint and caches it, renders purposes and vendors with the v2.2 plain-language names, builds a spec-compliant TC string with the iabtcf encoder using your configured CMP ID, and exposes __tcfapi with getTCData, ping and event listeners plus the __tcfapiLocator cross-frame bridge. It ships a synchronous queueing stub first, so vendor calls made before the full bundle loads are held and then flushed. Purpose and vendor choices flow into the same consent record as your other categories.
For an engineer, the practical test is simple. Open the console, call __tcfapi('getTCData', 2, console.log), and inspect the object — CMP ID, purpose and vendor consents, and eventStatus. If those are present and correct before your ad vendors initialise, the framework is doing its job, and your programmatic demand has the signal it needs to bid.