LW IT Solutions logo LW IT Solutions logo LW IT Solutions
« Blog Overview /Data Privacy / Reading a TC String: What Sits in...
Read this article in other languages:

Reading a TC String: What Sits in the 213 Header Bits

Reading a TC String: What Sits in the 213 Header Bits
Contents
  1. The fixed prefix: 213 bits, including purposes
  2. Dates and versions need separate interpretation
  3. Vendor sections: length is not a consent score
  4. Current rules beyond the bit layout
  5. Questions and answers
  6. Sources

A TC string stores transparency and consent signals in a compact format. Decoding reveals recorded values such as purpose flags, vendor choices and the referenced vendor-list version. It does not prove that the banner was correct, that a particular person gave valid consent or that a vendor respected the result.

The format is encoded, not encrypted. Reading requires no secret key. The string is also not a signed audit trail. A useful inspection therefore combines decoded signals with the actual dialogue, the matching Global Vendor List (GVL) and observed requests.

TC string: 213 fixed bits, then variable vendor sections
Encoded signals are not a signed record of consent

The fixed prefix: 213 bits, including purposes

Each segment uses the Base64url alphabet, with six bits represented by each character. Dots separate segments. The first six bits encode the format version: value 2 becomes 000010, represented by C. A leading C identifies this version field; it does not validate the remaining string.

The core starts with the following fields in order. Bit positions below are zero-based: position 0 is the first bit. The 213-bit prefix already contains the purpose flags. Vendor data starts at position 213, the 214th bit.

Field Bit positions Length
Version 0–5 6
Created 6–41 36
LastUpdated 42–77 36
CmpId 78–89 12
CmpVersion 90–101 12
ConsentScreen 102–107 6
ConsentLanguage 108–119 12
VendorListVersion 120–131 12
TcfPolicyVersion 132–137 6
IsServiceSpecific 138–138 1
UseNonStandardTexts 139–139 1
SpecialFeatureOptIns 140–151 12
PurposesConsent 152–175 24
PurposesLITransparency 176–199 24
PurposeOneTreatment 200–200 1
PublisherCC 201–212 12

The prefix ends after the first three bits of the 36th Base64url character. The remaining three bits belong to vendor data. Reading only 35 characters loses information; treating all 36 characters as the prefix consumes too much.

Dates and versions need separate interpretation

The timestamp fields retain 36-bit values expressed in tenths of a second since the Unix epoch. Under the current specification, however, Created and LastUpdated contain the same UTC day-level update timestamp. Multiplying by 100 converts the stored value to JavaScript milliseconds. The numeric unit does not establish tenth-of-a-second accuracy for the consent action.

An old update date is a reason to inspect renewal and reminder handling. A recent date alone is not proof of fresh consent, and a thirteen-month comparison does not reconstruct consent history. The technical specification discusses reminders at least every thirteen months; the string is not a substitute for the underlying evidence.

Format version 2, framework versions such as TCF 2.3 or 2.4, the policy version and the GVL version are different identifiers. A policy value of 4 was introduced with TCF 2.2; a value of 4 or higher is not proof that every current requirement has been implemented. VendorListVersion identifies the GVL snapshot used, not whether every vendor in that list appeared in the dialogue.

Vendor sections: length is not a consent score

A vendor section begins with a 16-bit maximum vendor ID and a one-bit encoding flag. Bitfield encoding then uses one bit per ID up to that maximum. Range encoding adds a 12-bit entry count. Each entry has a one-bit range flag and a 16-bit first or sole ID; a further 16-bit last ID appears only for a range.

For a maximum ID of 800, a bitfield occupies 817 bits including the section header. Fifty isolated IDs need 879 bits as ranges: 17 + 12 + 50 × 17. One contiguous range needs only 62 bits: 17 + 12 + 33. An encoder choosing the smaller representation would use the bitfield in the first example and the range in the second. Accepting everything is therefore not a universal guarantee of a short string.

Vendor consent and legitimate-interest signals occupy separate sections. Publisher restrictions and further segments also affect total length. A long string does not by itself mean broad consent, corruption or a large number of selected vendors.

Current rules beyond the bit layout

TCF 2.2 removed legitimate interest as an available basis for purposes 3–6. Purpose 1 already had consent as its permitted basis; its jurisdiction-specific PurposeOneTreatment flag is a separate matter. Special purposes have a separate numbering space and must not be read as ordinary purpose bits.

For the currently defined purposes 1–11, reserved positions 12–24 are not additional choices. Unexpected set bits deserve validation against the applicable specification and GVL. Such a finding establishes an inconsistency, not who wrote the implementation. Purpose signals alone also do not authorize every vendor: vendor signals, disclosures, declared purposes and publisher restrictions belong in the assessment.

TCF 2.3 made the DisclosedVendors segment mandatory for strings created from March 1, 2026. Earlier strings without that segment retain the transition exception; absence is therefore not automatically the same finding for every historical string. Segment type 1 records vendor disclosure, while optional type 3 describes publisher purposes. The former allowed-vendors segment, type 2, was removed in TCF 2.2.

TCF 2.4 subsequently introduced updated feature disclosures. The official implementation deadline was October 23, 2026 for web environments and is February 23, 2027 for mobile apps and CTV. Those changes do not turn the six-bit encoding version into 2.4. A bit decoder cannot verify the required wording and presentation of the dialogue.

Questions and answers

Is euconsent-v2 required?

No. The CMP chooses the storage mechanism; a different cookie name or non-cookie storage is possible. Absence of that cookie proves neither absence nor correctness of consent management.

Which browser API is appropriate?

getTCData was deprecated in TCF 2.2. The supported approach uses addEventListener, checks callback success and the CMP/event state, and reads tcString when available. The callback may initially contain incomplete data while the CMP loads. A one-time diagnostic reader should remove its listener with removeEventListener and the returned listener ID after obtaining the intended snapshot. An application following later choice changes must retain a suitable subscription.

How can incomplete data be detected?

A decoder checks the alphabet, field lengths, entry counts, ranges and segment types. Base64 decoding alone checks none of the policy rules. For byte-oriented decoders, Base64url alphabet conversion and any required padding apply separately to each segment. Direct conversion from each character to six bits avoids byte-boundary assumptions.

Unexpectedly missing bits can result from copying, storage, encoding or transport errors. A length limit is one possible cause, not a diagnosis. RFC 6265 recommends that general-purpose browsers support at least 4096 bytes per cookie including name, value and attributes; the requirement is SHOULD, not MUST. Oversized cookies or request headers can be rejected rather than silently truncated. Comparison of the stored value, CMP API output and transmitted value helps locate the discrepancy.

What belongs in a practical review?

A repeatable review records the chosen test action, the corresponding UI state, decoded purpose and vendor signals, relevant restrictions and the matching GVL snapshot. Network observation then checks whether processing follows the expected decision. None of those individual checks establishes comprehensive legal compliance.

Lukas Wojcik

Lukas Wojcik

Systems architect and technology enthusiast specializing in scalable tracking solutions, GMP Stack (GA4 & GTM), and robust backend architectures. Advocate for clean code and privacy-first design.

Get in touch

A question or an idea for a web project? Tell me a little about it. This form uses reCAPTCHA to protect against spam.

Write a comment

Observations from other implementations, objections and questions are welcome here.

The email address is not published. Required fields are marked with an asterisk.