Skip to content
TCF v2

TC String Decoder

Paste the consent string from the euconsent-v2 cookie and see the CMP, the purposes and the vendor ids inside it.

The string stays in this tab. Nothing you paste is sent to the server.

What a TC string actually is

A TC string is the record a CMP writes when someone accepts, rejects or saves a choice on a European consent banner. You will usually find it in the cookie named euconsent-v2. Open the cookies on a site that shows that banner and look for a long value that starts with C. That value is the string.

The format is a bit field, written with the base64url alphabet: A to Z, a to z, 0 to 9, and the characters - and _. The first six bits are the version. TCF 2 stores a 2 there, and six bits is exactly one character, so the first letter comes out as C. That is why a current string almost always starts that way. After the version come two timestamps, counted in tenths of a second since 1 January 1970: when the string was created, and when the CMP last updated it. Then the CMP id, the CMP build number, the screen where the choice was saved, and the language of the banner. Each letter of that language is a number from 0 (A) to 25 (Z).

Next is the version of the Global Vendor List used to build the banner, and the TCF policy version from that same list. IsServiceSpecific has to be 1. A 0 means a vendor should treat the string as invalid under the policy, even when the rest of the bits still parse. UseNonStandardTexts is 1 when the CMP changed the standard purpose texts or the illustrations. PurposeOneTreatment is 1 when Purpose 1 was not disclosed in the usual way. PublisherCC is the country whose law the publisher is using as the reference, two letters, same encoding as the language.

Purposes take twenty-four bits of consent and twenty-four bits of legitimate interest. Purpose 1 is the first bit in each row: store or access information on a device. Only purposes 1 to 11 are named. From TCF 2.2, purposes 3, 4, 5 and 6 (ad profiles and content profiles) cannot use legitimate interest, so those four legitimate-interest bits are required to be 0. Special features are a separate row of 12 bits. The two defined today are precise geolocation, and scanning device characteristics for identification. A 1 means the user opted in.

Vendor consent and vendor legitimate interest come after that. Each list starts with the highest vendor id it covers, then a flag: one bit per id, or a set of ranges. Ranges are smaller when the set is sparse, which is the usual case on a long vendor list. A vendor missing from a range list has no signal. The id is the number in the Global Vendor List, not a company name. IAB Europe republishes that list often, so this page prints the number. The matching names are in https://vendor-list.consensu.org/v3/vendor-list.json for the current list, and in https://vendor-list.consensu.org/v3/archives/vendor-list-v{version}.json for the version stored in the string. Using today's file against an old string mislabels vendors that were removed.

Publisher restrictions close the core segment. Each record names a purpose, a restriction type and the vendor ids it covers. Type 0 means the publisher does not allow that purpose for those vendors. Type 1 means the publisher requires consent, including when the vendor registered the purpose under legitimate interest and marked it flexible. Type 2 requires legitimate interest instead. The count of restrictions is always present, including when it is zero.

Dots split the string into segments. The first segment is the core and has no segment type: it starts with the version. Every later segment starts with a 3-bit type. Type 1 is Disclosed Vendors, the ids the CMP actually showed to the user. Since TCF 2.3 that segment is required, because a vendor that only declares special purposes had no other field where a CMP could mark it as disclosed. Type 3 is the Publisher TC: the purposes the site asks for itself, plus any custom purposes the publisher defined. Type 2 is the old Allowed Vendors segment from the out-of-band design. Current CMPs do not write it. An old string that still has it is decoded and labelled on its own.

A tilde is outside TCF. Everything after ~ is Google Additional Consent: a version number, then ATP ids separated by dots. CMPs append it to the same cookie so an ad tag can read providers that are not on the Global Vendor List. This page splits that tail off and lists the ids. It does not call Google, and it does not look the ATP ids up.

Where to copy it

  1. In Chrome, open DevTools, Application, Cookies, then the site. Copy the value of euconsent-v2. If the CMP stored Additional Consent in the same cookie, keep the part after the tilde.
  2. On a page where the CMP is loaded, run this in the console: __tcfapi("getTCData", 2, function (data) { console.log(data.tcString); }). tcString is the core plus the dot segments. When the CMP also fills addtlConsent, that value is what belongs after the tilde.
  3. Bid requests often repeat the same value as gdpr_consent or euconsent. A long URL gets cut. A cut string fails on this page with a message that it ended early. The cookie is the copy to trust.

How to read the result

Dates are shown in your language and again in UTC. Created is the first time this choice was stored. Last updated moves when the CMP rewrites the string, including a refresh of the vendor list.

The CMP line names a few companies from the current IAB Europe CMP list: Usercentrics (5), Sourcepoint (6), Didomi (7), OneTrust (28), consentmanager (31), Sirdata (92), Cookiebot (134) and Google (300). Any other id stays a number. Companies get added and renamed, and a guessed name is worse than the id.

The purpose table is purposes 1 to 11. Yes means that bit is set. Legitimate interest on purposes 3 to 6 should be off on a string built under TCF 2.2 or later. If you see it on, the CMP that wrote the string did not follow that rule.

Each vendor block shows a count, the highest id, whether the encoding was bits or ranges, and then the ids. Past 200 ids the rest is counted and not printed, so a full opt-in does not lock the tab. Disclosed Vendors, when the segment is missing, gets a line that says so. On a TCF 2.3 string that segment should be there.

Questions that come up with this string

Where is the TC string stored?

In the cookie euconsent-v2 on almost every CMP that implements TCF 2. Some stacks also put it on the bid URL. Copy from the cookie when you can. A value taken from a long URL is often cut off, and a cut string will not decode.

Why does it start with C?

The version is the number 2, stored in six bits. Six bits is one base64url character, and the character for the value 2 is C. A TCF 1 string starts with a different character because the version number is different. This page only opens version 2.

What is the difference between the consent column and the legitimate interest column?

Consent is a bit the user turned on. Legitimate interest is a bit the CMP sets when it disclosed that purpose under legitimate interest and the user did not object. A vendor still has to read its own row in the Global Vendor List. A purpose registered as consent is not covered by the legitimate-interest bit.

What is purpose 1?

Store and/or access information on a device. It is the purpose that covers cookies and similar storage, and the TCF policy requires consent for it. PurposeOneTreatment, higher up in the same string, tells a vendor whether the CMP disclosed purpose 1 in the normal way. With the publisher country code, that is how a vendor decides if it still needs a yes for purpose 1 in that country.

Why are there dots in the middle?

Each dot starts another segment. The core comes first. After it you usually see Disclosed Vendors and, on some sites, the Publisher TC. The order of those later segments does not matter, because each one starts with its type.

What is the text after the tilde?

Google Additional Consent. The first number is the AC version, then a list of ATP provider ids. CMPs store it next to the TC string so a Google ad tag can read both. It is not a TCF segment and it is not base64.

Do you upload what I paste?

No. The script on this page reads the box and writes the result under it. There is no request that contains the string. Close the tab and it is gone.

Can this decode a TCF v1 string?

No. Version 1 uses a different layout. If the first six bits are not 2, the page stops and shows the version it found.

The vendor list is only numbers. Where are the company names?

The string stores ids. Names live in the Global Vendor List for the version printed next to Vendor list on this page. The current file is https://vendor-list.consensu.org/v3/vendor-list.json and an older one is https://vendor-list.consensu.org/v3/archives/vendor-list-v{version}.json, with the version from the string in place of {version}. Today's list against an old string puts the wrong name on vendors that were deleted.

What is a CMP id?

A number IAB Europe assigns to the company that collects the consent. It is not the publisher, and it is not a vendor id from the Global Vendor List. The CMP version next to it is that company's own build number. It is the field you want when a bug only shows up in one release of their banner.