Guide
What is an analytics payload, and why decode it?
Every analytics hit your site sends is a URL — usually with 30 to 80 query parameters jammed together, percent-encoded, and shipped to /g/collect or /mp/collect in a fraction of a second. To the browser it's just a request. To you, debugging why a conversion never showed up in GA4, it's the only ground truth you have.
The Tagfire Payload Decoder takes that URL — or the JSON body from a server-side request — and unpacks every parameter into something a human can read: the event name, the user identity, the consent state, the e-commerce items, the custom dimensions, and what each parameter actually does in GA4.
Why decoding the payload matters
GA4's main reports are delayed. DebugView shows what GA4 received and accepted, but only for sessions you have explicitly opted into debug mode — and it does not show what your site sent, only what survived processing. When a conversion goes missing, the only artefact you can fully trust is the raw network request that left the browser. But the raw request is unreadable on its own:
- A 1,200-character URL with
%2F,%3A, and+in every value - Parameters named
en,ep.*,epn.*,_et,gcs— no human meaning until you look them up - A JSON body on top of the query string in Measurement Protocol calls, both carrying different parts of the same event
- No obvious way to tell whether the consent flags you set in your CMP are actually being honored
A decoder turns "I think this is broken" into "I know exactly which parameter is wrong" in about ten seconds.
What's in a typical GA4 payload
When you paste a request, the decoder splits it into three layers and labels everything. The same structure applies to gtag.js hits, server-side Measurement Protocol calls, and custom proxied endpoints.
Endpoint & transport
The collection URL itself — google-analytics.com/g/collect, a server-side /mp/collect, a custom-domain first-party proxy, or a regional endpoint. The decoder flags non-standard endpoints so you spot first-party server-side and third-party proxies at a glance.
Hit-level parameters
Values that apply to the whole hit — measurement ID (tid), client ID (cid), session ID (sid), user agent hints, consent state (gcs / gcd), debug flag (_dbg), and timing offsets. These are the parameters most likely to be misconfigured during a consent-mode rollout.
Event-level parameters
The event name (en) plus everything specific to it — page location (dl), referrer (dr), engagement time (_et), and your custom event parameters (prefixed ep. for strings, epn. for numbers). E-commerce events carry the items array — sometimes URL-encoded in the query string, sometimes in the JSON body when it does not fit.
Five things you can spot in a payload
Once a payload is decoded, the same problems show up in almost every broken implementation. They are usually invisible in the GA4 UI until days later, but they are obvious in the raw hit:
- 1
Missing or duplicated client_id (cid)
The most common GA4 attribution bug. Two different `cid` values across two events means the user is being counted as two people. No `cid` at all usually means the GA4 cookie was blocked or your custom implementation skipped setting it.
- 2
Consent flags that contradict your CMP
`gcs` and `gcd` carry the Consent Mode state. If the user denied analytics consent but the payload shows `gcs=G111` (everything granted), your Consent Mode wiring is wrong. The decoder labels each consent bit so you do not have to memorize the bitmask.
- 3
Wrong measurement ID (tid)
Surprisingly common after a property migration. The container still points at the old `G-XXX` and you are sending traffic to a deprecated property. The decoder shows it on the first line, so this is the fastest 30-second check in any audit.
- 4
Missing parameters on conversion events
Your `purchase` event fires, but `ep.transaction_id` is empty, `epn.value` is zero, or the `items` array is missing. The decoder pretty-prints items and flags which required parameters are absent for that event type.
- 5
Broken engagement time (_et)
`_et` should be the milliseconds since the last hit. Values of 0, negative numbers, or 30-second-plus intervals on every hit usually mean the engagement timer is broken — common after a single-page-app routing change that did not re-initialise gtag.
When decoding beats GA4 DebugView and Tag Assistant
DebugView and Tag Assistant are great for fast iteration in your own browser. The Payload Decoder wins when you need the ground truth — what the network actually carried, regardless of whose browser produced it.
Use the decoder for
- • Confirming what the browser actually sent
- • Auditing server-side container output
- • Inspecting consent flags on a denied user
- • Reading a hit captured from someone else's browser
- • Decoding bug reports a client sent you weeks ago
Use DebugView / Tag Assistant for
- • Watching events stream in real time
- • Browser-side trigger testing
- • Verifying tag firing in GTM preview mode
- • Anything that requires a debug cookie
The decoder accepts a raw URL pasted from anywhere — Chrome DevTools, a proxy log, a customer's bug report. It needs no access to the GA4 property and no debug cookie.
What a payload cannot tell you
Three things are not in the request at all. You still need other tools for:
- Whether GA4 actually processed the hit. The request leaving the browser does not guarantee GA4 ingested it. Network filtering, IP blocks, and data-quality rejections all happen after the fact.
- Server-side container internals. If you are seeing the outbound hit from server-side GTM, the input from the browser is a different request you also need to capture and decode.
- Final channel attribution. The payload carries
gclid,_gl, and campaign parameters, but how GA4 chooses to attribute a conversion to a channel happens inside Google's processing layer, not in the request.
For everything that does live in the payload, the decoder is the source of truth.
The static view and the runtime view
Together, the two free Tagfire tools cover the static structure of your container and the runtime output it produces. Use the free GTM Visualizer to see what should fire — then catch a real hit in DevTools and paste it into the decoder to confirm what actually fired, with the right parameters, in the right consent state. That round-trip is what every audit comes down to.