Consent state: a typed field on each event, not a switch on the page
In short
Consent state is an attribute of each event, not a property of the page. Every event carries the user's answer for the purposes you use — analytics storage, ad storage, ad user data, ad personalisation — as it stood when that event fired. Tags declare a default before anything measures and update it on the answer, which makes an event with no consent field a defect rather than a permitted case.
Key takeaways
- Consent is per event, not per page. Events fired before and after the banner answer legitimately carry different values.
- The 4 purposes to model are analytics storage, ad storage, ad user data and ad personalisation; the fuller vocabulary adds functionality, personalisation and security storage.
- Declare a default before any measurement loads, then update on the answer, on the page where the answer happened.
- Treat a missing consent field as a pipeline defect. An event that cannot say what it was permitted to do cannot be safely processed later.
Consent state is a typed field carried by each event, recording what the user had permitted when that event fired. It is not a page-level switch and not a single boolean. Model it as a small set of named purposes, each granted or denied, attached to every event you send — including those that fire before anyone has answered anything.
That last part is what the per-event framing buys. A pageview at 400 ms and a purchase 4 minutes later are both correct records carrying different consent values, because the user answered in between. A design that stamps one page-level value on everything has to choose which of the two to be wrong about.
The vocabulary, and what each purpose governs
| Purpose | What it governs | Typical effect when denied |
|---|---|---|
| analytics_storage | Reading and writing analytics identifiers on device | Events may still be sent, but without a persistent identifier to join them |
| ad_storage | Advertising cookies and stored click identifiers | A click identifier is not persisted, so a later sale cannot be tied back to it |
| ad_user_data | Sending user data to an advertising platform at all | The platform receives no user data for that event |
| ad_personalization | Using the data for personalised advertising | Data may serve measurement but not personalisation or audiences |
Google's tags carry this state on the request itself, as compact consent parameters — gcs for the storage state at hit time, gcd for the defaults-and-updates picture. Do not decode either from memory or a blog post: the encodings are terse and they change. Read the current definitions from Google's own tag platform documentation before building anything that parses them.
Default, then update
- Set defaults before any measurement command runs. Every purpose gets an explicit value, and regional defaults are declared here if policy differs by region.
- Load measurement. Anything firing now carries the defaults, and is still sent rather than suppressed if policy allows a consentless signal.
- The user answers. Send the update on the page where the answer happened, before any navigation — a transition recorded after a page change has already lost the events it should have governed.
- Persist the answer so the next page's default is the user's actual choice, not denied again.
- Stamp the current state onto every event as it is constructed, not once at page load.
One visit, event by event
| Event and time | Consent at fire time | What the request could carry |
|---|---|---|
| page_view, 0.4 s | Defaults: analytics denied, ads denied | No stored identifier; consent parameters present |
| scroll, 6 s | Unchanged | Same as above — a second consentless signal |
| banner accept, 9 s | Update: all four granted | Not an event; a state transition |
| view_item, 11 s | All granted | Full payload, identifier now written and attached |
| purchase, 240 s | All granted | Full payload plus the stored click identifier |
Rows 1 and 2 are the interesting ones. Those events happened, and no stored identifier joins them to rows 4 and 5. Anything downstream that assumes otherwise — a session model, a funnel, a first-touch rule — quietly invents a join. The asymmetry shows up in the raw data too, which is why it pays to know what one row of the event export holds first.
Consent is not a gate you pass through once. It is a value that travels with the record, and a record that cannot say what it was permitted to do is a record you cannot safely process.
What the field decides downstream
Denied ad storage has the sharpest downstream effect: with no persisted click identifier there is nothing to join a sale back to the click, the subject of the parameters that tie a click to a sale. It also constrains deduplication, since a browser copy and a server copy of one conversion must agree on the consent state and on the shared value that says they are one conversion.
The engineering posture worth copying comes from declared fields elsewhere in advertising: present and complete on every request, checked at the boundary, an incomplete value treated as a failure — the standard applied to the supply chain object and what complete means. That check belongs in the build rather than a later hardening pass, which is how we scope MVP and product builds. The surrounding decisions sit under tracking, consent and event pipelines in the marketing and advertising practice.
Frequently asked questions
Short answers to the follow-ups this page tends to raise.
Is consent state the same as the cookie banner?
No. The banner is the interface that collects an answer; consent state is the machine-readable representation of it, carried on every event afterwards. They fail independently: a banner can collect a valid answer that never reaches the measurement layer, and a measurement layer can carry a state that no longer matches what the user chose.
Should events still be sent when consent is denied?
That is a policy decision for your organisation and its counsel, not a technical default. Both designs exist: suppress the event, or send a signal carrying the denied state and no persistent identifier. What matters is that the choice is explicit and encoded in the event — a pipeline that sometimes sends and sometimes does not, with no field saying which, produces data nobody can interpret.
How is consent passed to a tagging server?
As fields on the same request that carries the event. The page attaches the current state, the server reads it first, and each outbound vendor request is shaped by what that state permits. The property that matters is ordering: read consent before enriching or forwarding, or a transformation can attach data the event was never permitted to carry.
Does a granted state make historical denied events usable?
No. Consent applies from the moment it is granted, so events collected under a denied state stay as collected — usually without a persistent identifier, and so not joinable to what came after. Retro-fitting an identifier onto them is the invented join to avoid. Treat pre-consent events as a separate population.
- consent
- event pipelines
- measurement
- data governance
The work behind this page
Builds from our portfolio that this page draws on.
Read next
- The tagging server: a first-party endpoint that owns the payloadA tagging server is not a proxy. It parses one first-party event, adds and strips fields, and emits a vendor-shaped request per destination from your infrastructure.definition
- Event ID: the value that lets two systems agree a conversion happened onceThe same identifier, the same conversion, both transports, inside the platform's window. Four generation strategies, and the guarantee each one keeps or breaks.definition
- The exported event row: nested parameters and no session columnOne row per event, a repeated parameter struct with four typed slots, and a pseudonymous identifier that can be missing. Every figure a report shows is derived from this.definition
Working on something in this space?
Tell us where you are in a sentence or two. We'll tell you honestly whether we're the right team, and what a sensible first slice of the work looks like.
Start the conversation