GPP (Global Privacy Platform) is the privacy signal protocol published by IAB Tech Lab: it encapsulates consent and choice signals from multiple jurisdictions into a single string carried along the ad chain. One mental model is enough to understand it — GPP is the outer envelope, and TCF is merely the payload of one of its sections. This page builds that model first, then walks a real string through the decoder, and only then lays out the full reference tables.
On this page
- Mental model: GPP is the envelope, sections are the letters
- Walk through: how a real string gets decoded
- Try your own string
- String structure & Header
- Encoding data types
- Section registry (official IDs 1–27)
- TCF EU v2 · TC String
- Segments
- Core String field layout
- Purpose names (TCF 2.2)
- USPrivacy String (deprecated)
- Transport: URL macros · OpenRTB · CMP API
- Data sources & baseline
Mental model: GPP is the envelope, sections are the letters
A GPP string is a set of payloads, each governed by its own specification, joined by ~ and preceded by a table of contents (the Header). The contents only say which letters are inside; each letter is written according to its own spec.
DBACNYHeader · contents
Only declares which letters are inside; carries no consent signal
CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAASection 2 · EU TCF v2
Payload · bit layout defined by that section's own spec
1YNNSection 6 · USPrivacy String (Unencoded)
Payload · bit layout defined by that section's own spec
① The Header is only a table of contents
The Header has just three fields — Type / Version / Sections — declaring which section IDs the string carries. It holds no consent or opt-out signal itself. To learn what the user actually agreed to, you must open the corresponding section.
② Bit layouts belong to each section's own spec
GPP does not define section internals, so the bit layouts of EU TCF v2, US National and the individual US states are independent documents. This site currently decodes section 2 (EU TCF v2) and section 6 (USPrivacy) down to field level; for the rest it identifies the ID and Version and links to the official spec.
③ The first character is an identification convention
A leading D means an enveloped GPP string; a leading C means no envelope at all — the string is directly an IAB Europe TCF v2 TC string. This backward-compatible convention is how a decoder picks its entry point.
Who writes it · who carries it · who reads it
1
Writes: the CMP
The consent management platform produces the string in the browser and exposes it through the __gpp() queue and the window.__gpp callback.
2
Carries: the ad chain
Travelled with the request: the URL macros gpp / gpp_sid, or regs.gpp / regs.gpp_sid since OpenRTB 2.6.
3
Reads: vendors
DSPs and exchanges decode the Header to find the sections in force, then decode consent and opt-out signals per that section's spec, and bid or serve accordingly.
Walk through: how a real string gets decoded
Fibonacci coding and bitfields stay abstract until you watch a real string being read bit by bit. Below, an official sample is walked through in four stages: each step highlights the base64 characters and the bit range the current field covers, and shows the value read.
Sample · official GPP String Example 2DBACNY~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN
Full sample string
DBACNY~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNNSegment being read
DBACNY~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN- Encoding
- modified base64
- Bit range
- Character-level split; this step reads no bits
- Char range
- chars[0..6)
Header
Value read
DBACNY
The whole string is split by ~ into 3 parts: the first is the Header, and every remaining part is one section's payload. The Header declares section IDs [2, 6] for this transaction.
Ordered list of Section IDs contained in the string; IDs appear in the same order as their sections. Fibonacci range: int(12) amount, then per item a single/group bit + Fibonacci offset (from last seen ID, 0-based for the first entry), groups add a Fibonacci length.
Step 1 of 29: Header, modified base64, value DBACNY
Try your own string
Open the decoder in its own page →The walkthrough uses a fixed official sample. Replace the input below with a string captured from production to see the full field-level result, including the variable-length Vendor sections the walkthrough does not cover. All parsing happens locally in your browser; strings are never uploaded.
GPP Header
GPP v1Sections declared by the header: [2, 6]
Section 2 · EU TCF v2
tcfeuv2Core String
TCF v2Section 6 · USPrivacy String (Unencoded)
uspv1String structure & Header
[Header]~[Discrete Section]~[Discrete Section]…- ~ — Section delimiter: joins the Header and each section payload in order
- . — Sub-segment delimiter inside a section (e.g. the segments of a TC String)
- modified base64 (RFC 4648 table, 6 bits per character, right-padded with 0 to a multiple of 6 bits)
A leading D (bits 000011 → base64 index 3) marks a GPP string; a leading C (000010 → 2) marks an IAB Europe TCF v2 TC string — a backward-compatible recognition convention carried over from the older format.
| Field | Type | Description |
|---|---|---|
| Type | Int(6) | Fixed to 3 as "GPP Header field". |
| Version | Int(6) | Version of the GPP spec (currently 1). |
| Sections | Range(Fibonacci) | Ordered list of Section IDs contained in the string; IDs appear in the same order as their sections. Fibonacci range: int(12) amount, then per item a single/group bit + Fibonacci offset (from last seen ID, 0-based for the first entry), groups add a Fibonacci length. |
Encoding data types
This table is the reading key for every field table below: the terms used in the TC String — Range(Fibonacci), N-Bitfield, Datetime and friends — are all defined here, so it is worth a scan before going further.
| Name | Encoding | Description |
|---|---|---|
| Boolean | 1 bit | 0=true, 1=false in the GPP JS API output convention (section-specific docs define meaning). |
| Integer (fixed) | x bits | Fixed-length integer; usual lengths 3, 6, 12, 16, 24, 36 bits. |
| Integer (Fibonacci) | variable | Fibonacci-coded integer; bit sequence always ends with "11". |
| String (fixed) | x×6 bits | Each character: ASCII − 65 as Int(6); used for language/country codes. |
| Datetime | 36 bits | Deciseconds since 1970-01-01 UTC (Math.round(Date.now()/100)). |
| Bitfield (fixed) | x bits | One boolean per ID; first bit ↔ ID 1. |
| N-Bitfield | Int(16) length + bitfield | Variable-length bitfield prefixed by its length. |
| Range (Int) | variable | int(12) count, then per item: single/group bit + int(16) start (+ int(16) end for groups); not necessarily sorted. |
| Range (Fibonacci) | variable | int(12) count, then per item: single/group bit + Fibonacci offset from last seen ID (+ Fibonacci group length); must be sorted. |
| OptimizedRange | variable | Boolean switch: 1 → Fibonacci Range; 0 → variable-length bitfield. |
| ArrayOfRanges / N-ArrayOfRanges | variable | int(12) record count; per record key + type + id collection (legacy downward-compatible shape). |
Section registry (official IDs 1–27)
Core sections (IDs 1–7)
| ID | CMP API prefix | Name | Jurisdiction | Status |
|---|---|---|---|---|
| 1 | tcfeuv1 | EU TCF v1 ↗ | EU | deprecated |
| 2 | tcfeuv2 | EU TCF v2 ↗decoded to field level here | EU/EEA | current |
| 3 | — | GPP Header ↗ | — | required |
| 4 | — | GPP Signal Integrity ↗ | — | reserved |
| 5 | tcfcav1 | Canadian TCF ↗ | CA | current |
| 6 | uspv1 | USPrivacy String (Unencoded) ↗decoded to field level here | US | deprecated |
| 7 | usnat | MSPA US National ↗ | US | current |
US state sections (IDs 8–27, 20 in total)8–27
Each US state section has its own, structurally very similar bit layout; field-level decoding is not collected here yet. Expand for IDs, CMP API prefixes and official spec links.
- 8uscaUS – California
- 9usvaUS – Virginia
- 10uscoUS – Colorado
- 11usutUS – Utah
- 12usctUS – Connecticut
- 13usflUS – Florida
- 14usmtUS – Montana
- 15usorUS – Oregon
- 16ustxUS – Texas
- 17usdeUS – Delaware
- 18usiaUS – Iowa
- 19usneUS – Nebraska
- 20usnhUS – New Hampshire
- 21usnjUS – New Jersey
- 22ustnUS – Tennessee
- 23usmnUS – Minnesota
- 24usmdUS – Maryland
- 25usinUS – Indiana
- 26uskyUS – Kentucky
- 27usriUS – Rhode Island
TCF EU v2 · TC String
IAB Europe TCF v2 (policy version 4 since TCF 2.2; strings with policy < 4 invalid after 2023-09-30)
[Core String].[Disclosed Vendors].[Publisher TC] — segments after the core are "."-separated and self-identified by a 3-bit SegmentTypeSegments
Basic vendor transparency & consent; always first, no SegmentType prefix.
Vendors disclosed to the user by the CMP. Mandatory since TCF 2.3 (Apr 2025) to resolve special-purpose LI ambiguity.
Publisher's own purposes transparency & consent, incl. custom purposes.
Core String field layout
The bit ranges are the cumulative widths from the table above — the very same source as stage four of the walkthrough; the last row is the variable-length trio whose width is decided by the data itself.
| Field | Bits | Bit range | Description |
|---|---|---|---|
| Version | 6 | bits[0..6) | Encoding format version (2). |
| Created | 36 | bits[6..42) | Epoch deciseconds when the TC string was first created. |
| LastUpdated | 36 | bits[42..78) | Epoch deciseconds of the last update (since Dec 2021 kept equal to Created at day-level resolution). |
| CmpId | 12 | bits[78..90) | ID of the CMP that last updated the string. |
| CmpVersion | 12 | bits[90..102) | Version of that CMP. |
| ConsentScreen | 6 | bits[102..108) | CMP screen number where consent was given. |
| ConsentLanguage | 12 | bits[108..120) | ISO 639-1 language of the CMP UI (2×6 bits, a=0…z=25). |
| VendorListVersion | 12 | bits[120..132) | Global Vendor List version used. |
| TcfPolicyVersion | 6 | bits[132..138) | TCF policy version of the GVL (4 since TCF 2.2). |
| IsServiceSpecific | 1 | bits[138..139) | Must be 1; a string with 0 is considered invalid by vendors. |
| UseNonStandardTexts | 1 | bits[139..140) | CMP modified standard stack/illustration texts. |
| SpecialFeatureOptIns | 12 | bits[140..152) | Opt-in per Special Feature (1–2). |
| PurposesConsent | 24 | bits[152..176) | Consent per Purpose 1–24 (legal basis: consent). |
| PurposesLITransparency | 24 | bits[176..200) | Legitimate interest per Purpose; TCF 2.2 deprecated LI for purposes 3–6 (bits must be 0). |
| PurposeOneTreatment | 1 | bits[200..201) | 1 = Purpose 1 not disclosed (special treatment by jurisdiction). |
| PublisherCC | 12 | bits[201..213) | ISO 3166-1 alpha-2 country determining the legislation of reference. |
| VendorConsents + VendorLI + PubRestrictions | variable | bits[213..) | Vendor Consent Section and Vendor Legitimate Interest Section (MaxVendorId int(16) + bitfield or range), then NumPubRestrictions int(12) with optional restriction entries (PurposeId 6 + RestrictionType 2 + vendor range). |
Purpose names (TCF 2.2)
- P1Store and/or access information on a device
- P2Use limited data to select advertising
- P3Create profiles for personalised advertising
- P4Use profiles to select personalised advertising
- P5Create profiles to personalise content
- P6Use profiles to select personalised content
- P7Measure advertising performance
- P8Measure content performance
- P9Understand audiences through statistics or combinations of data from different sources
- P10Develop and improve services
- P11Use limited data to select content
Special Features (TCF 2.2)
- SF1Use precise geolocation data
- SF2Actively scan device characteristics for identification
Purpose names follow the official wording of IAB Europe TCF Policies / the Global Vendor List (TCF 2.2 revision); 11 was added in 2.2 and 12–24 are reserved.
USPrivacy String (deprecated)2024-01
Deprecated by the IAB in 2024-01 and superseded by GPP section 6; legacy traffic and some platform parameters still pass it directly, so it is honestly kept for debugging. It is also a ready-made example of a section payload that needs no bit encoding: four plaintext characters map one-to-one onto four fields.
4 characters: version · explicitNotice · optOutSale · lspaCoveredTransaction| # | Field | Type | Description |
|---|---|---|---|
| 1 | version | 1 | String specification version (always 1). |
| 2 | explicitNotice | Y / N / - | Explicit notice/opportunity provided: Y yes, N no, - not applicable. |
| 3 | optOutSale | Y / N / - | User opted out of sale/sharing: Y opted out, N did not, - not applicable. |
| 4 | lspaCoveredTransaction | Y / N | Transaction covered by the IAB Limited Service Provider Agreement. |
Transport: URL macros · OpenRTB · CMP API
| URL | Macro | Description |
|---|---|---|
| gpp | ${GPP_STRING_XXXXX} | URL-safe encoded GPP string; XXXXX is the receiving vendor's GPP ID. Vendors without a GPP ID may receive ${GPP_STRING}. |
| gpp_sid | ${GPP_SID} | Section ID(s) in force for the transaction; normally a single ID, rarely two comma-separated. |
- OpenRTB · Since OpenRTB 2.6-202211: regs.gpp (the string) and regs.gpp_sid (array of section IDs); before that, platforms carried it in proprietary fields such as regs.ext.gdpr_consent / user.ext.consent.
- CMP API · In the browser it is read via the __gpp() queue and the window.__gpp callback (GPP CMP API v1.1, 2023-06); before TCF 2.2 the entry point was __tcfapi().
Data sources & baseline
Collected baseline
GPP String v1.0 (published 2022-09-28, clarifying revision 2023-11-03) + TCF EU v2 TC String (Final v.2.2 baseline incl. the 2.3/2.4 revisions). The section registry follows the latest official Section Information.md (IDs 1–27).
Official repositories & fetch record
GPP string format & Section registry: official repository InteractiveAdvertisingBureau/Global-Privacy-Platform · commit 03fdf03 · fetched 2026-08-31 · CC-BY 3.0 (IAB Tech Lab)
TCF EU v2 TC String field layout: TCFv2/IAB Tech Lab - Consent string and vendor list formats v2.md (Final v.2.2 baseline incl. 2.3/2.4 revisions) · fetched 2026-08-31 · CC-BY 3.0 (IAB Tech Lab) / IAB Europe
Field descriptions follow the official IAB English wording; other languages on this site are translations. On the zh page the English annotation can be hidden with the bilingual toggle at the top.