Server-side GTM clients and tags reference
last verified · against Google server-side Tag Manager documentation as of 2026-07
Server-side GTM clients and tags reference: the five built-in clients, request claiming, priority, activation criteria, client APIs, and GA4-to-Ads chaining.
What this is
In server-side Tag Manager, clients are adapters between the software running on a user’s device and your server container: they receive measurement data from a device, transform that data into one or more events the container understands, process those events through the container’s tags and triggers, and package the results to be sent back to the device. Every incoming request is offered to each client in priority order — highest priority first — and the first client whose activation criteria match claims the request, after which no further client runs.
The four client functions
| # | Function | Detail |
|---|---|---|
| 1 | Receive | Takes measurement data from the device |
| 2 | Transform | Turns the data into events the container understands |
| 3 | Process | Runs the events through the container’s tags and triggers |
| 4 | Package | Packages the result to send back to the requester |
Events are named, measurable occurrences (for example click,
start_toasting). After a client transforms an incoming request into events,
those events pass through the container’s tags, triggers, and variables.
Built-in clients
Server containers ship with a fixed set of built-in clients; you cannot add clients from the template gallery. Google’s official pages confirm only the first two as pre-installed. The full five-client enumeration and the “runs the container” distinction come from third parties (Adswerve, Stape).
| Client | Runs the container? | Role | Attribution |
|---|---|---|---|
| Google Analytics: GA4 | Yes | Builds the event-data object, runs the container, fires tags | Pre-installed (Google official) |
| Measurement Protocol | Yes | Accepts Measurement Protocol events for mobile apps and server-to-server | Pre-installed (Google official) |
| Google Analytics: Universal Analytics | Yes | Builds event data and runs the container | Adswerve / Stape |
| Measurement Protocol (GA4) | Yes | Builds event data and runs the container | Adswerve / Stape |
| Google Tag Manager: Web Container | No | Serves the gtm.js library first-party; does not run the container |
Adswerve / Stape |
- The GA4 client and the Measurement Protocol client are the two that Google’s documentation lists as pre-installed by default in a new server container.
- Clients that run the container (GA4, Universal Analytics, Measurement
Protocol, Measurement Protocol GA4) are the ones that generate events and fire
tags. A loader/proxy client such as the Web Container client does not run the
container — it fetches and serves libraries first-party and uses
sendHttpRequestto route requests, returning status, headers, and body. - Google frames gtag handling as a mode of the GA4 client (its “Default gtag.js paths” setting), not as a separate built-in “gtag” client.
Client configuration
| Setting | What it controls |
|---|---|
| Priority | Order in which clients run. Higher numbers run first; the first client that matches the incoming request becomes the active client for that request. |
| Activation Criteria | Define when the client will respond to requests (for example, the default gtag.js paths for specific IDs). |
Only one client can claim a single request, so priority ordering matters when
multiple clients listen for similar patterns. For a single-client setup,
InfoTrust recommends priority 0; Google’s own documentation states only the
“higher numbers run first” rule, not the shipped default priority numbers.
GA4 client activation
The GA4 client is pre-installed by default. It exposes two activation options.
| Activation option | Claims | Scope |
|---|---|---|
| Default GA4 paths | /collect, /g/collect, /j/collect |
GA4 event beacons |
| Default gtag.js paths for specific IDs | /gtag/js?id=TAG_ID |
Serves the gtag.js loader first-party |
- “Default gtag.js paths for specific IDs” activates in response to requests to
the default gtag.js request paths, e.g.
/gtag/js?id=TAG_ID. Configure it by clicking Add Measurement ID to add one or more destination IDs. - That gtag.js-paths option applies only when gtag.js is placed directly in the page source. It does not apply when the Google tag is deployed through a (web) GTM container; in that case rely on the “Default GA4 paths” for event collection.
- The complete authoritative list of paths the GA4 client claims is only
partially confirmed on official pages.
/collect,/g/collect, and/j/collectare confirmed for “Default GA4 paths” and/gtag/js?id=TAG_IDfor the loader;/gtag/destinationcould not be confirmed on an official page and is not asserted here.
Measurement Protocol client
| Item | Value |
|---|---|
| Format accepted | Measurement Protocol (mobile apps and server-to-server) |
| Default path | None |
| Activation Path | Required — must match your server’s collection endpoint |
Unlike the GA4 client, the Measurement Protocol client is not auto-configured to claim any specific endpoint. It requires an explicit Activation Path or its inbound hits are never claimed and never become events.
Client sandboxed APIs
Request-reading APIs available to clients:
| API | Returns / does |
|---|---|
getRequestBody() |
The request body |
getRequestHeader(headerName) |
The value of a request header |
getRequestPath() |
The request path with the server container URL prefix and the query string stripped |
getRequestQueryParameters() |
The request query parameters |
getRequestMethod() |
The HTTP method, e.g. 'GET' / 'POST' |
getRemoteAddress() |
A string representation of the IP where the request originated |
Response-writing APIs:
| API | Does |
|---|---|
setResponseBody(body, encoding) |
Sets the response body |
setResponseHeader(name, value) |
Sets a response header |
setResponseStatus(statusCode) |
Sets the response status code |
setPixelResponse() |
Writes a 1x1 GIF with caching and content-type headers |
setCookie() |
Sets or deletes a cookie |
Lifecycle and claiming APIs (with associated permissions):
| API | Does | Permission |
|---|---|---|
claimRequest() |
Claims the request; once claimed, the container runs no additional clients. Throws if called in a tag or variable, or after the client returns (e.g. in async callbacks). | none |
runContainer(event, onComplete, onStart) |
Executes container logic with a given event. onComplete fires after all tags finish; onStart fires immediately before tags fire; both callbacks receive a bindToEvent function. |
run_container |
returnResponse() |
Flushes the response previously set by setCookie / setPixelResponse / setResponseBody / setResponseHeader / setResponseStatus. Defaults to HTTP 200, empty body, no headers. Recommended from client templates. |
return_response |
Event-data, identity, messaging, and MPv2 APIs:
| API | Returns / does |
|---|---|
getAllEventData() |
A copy of the event data |
getEventData(keyPath) |
The value at a dot-notation path |
getClientName() |
The current client’s name |
sendEventToGoogleAnalytics |
Sends a single event using Common Event Data to Google Analytics (used by the GA4 server-side tag path) |
addMessageListener |
Adds a function that listens for a message of a particular type |
sendMessage |
Sends a message of the specified type to a registered listener |
isRequestMpv2() |
Returns true if the incoming request is a Measurement Protocol V2 request |
extractEventsFromMpv2() |
Translates an incoming MPv2 request into a list of events |
getGoogleScript() |
Retrieves a resource from a predetermined set of Google scripts (used to serve gtag.js / gtm.js first-party) |
On-page wiring and GA4 to Google Ads chaining
The web page routes gtag data to the server container with server_container_url.
| Item | Value |
|---|---|
| Config option | gtag('config', 'TAG_ID', { 'server_container_url': 'https://analytics.example.com' }) |
| Effect | GA4 browser traffic is directed to the server container, where the GA4 client claims it |
Google Ads server-side conversion tracking chains off the same GA4-client events, which is why GA4 must be flowing through the server first.
| Component | Trigger | Behavior |
|---|---|---|
| GA4 Event tag (web container) | Key events | Sends events to the server container via server_container_url; the server-side GA4 tag then picks up the parsed event data from the GA4 client and forwards it onward |
| Conversion Linker tag (server) | All pages (fires on every request) | Enables Google Ads to transmit data to Tag Manager |
| Google Ads Conversion Tracking tag (server) | Custom event trigger matching your GA4 Event tag’s event name (or specific page URLs) | Automatically reads Transaction ID, conversion value, and currency code from ecommerce fields |
user_data |
— | The required parameter name for user-provided data to pass through to the server container |
Gotchas
- Preview shows “No client claimed the request” and the Client column reads “none”. Cause: no client recognizes the incoming path, or the path/method does not match any activation criteria (e.g. a trailing slash on
server_container_url, wrong method, or a custom endpoint the GA4 default paths do not cover). Fix: confirm the GA4 client is present with the correct “Default GA4 paths” and/or “Default gtag.js paths” enabled, remove any trailing slash fromserver_container_url, and verify the path and method match the client’s Activation Path. - Two clients could both match one request but the wrong vendor claims it. Cause: only one client can claim a request, and the first client in priority order that matches wins; overlapping activation paths collide. Fix: set distinct, non-overlapping Activation Paths and use Priority (higher number runs first) to force the intended client to evaluate first.
- Measurement Protocol hits from a server-to-server or mobile source are ignored. Cause: the Measurement Protocol client has no default activation path and claims nothing until configured. Fix: set an explicit Activation Path that matches the exact collection endpoint your sender posts to.
- The “Default gtag.js paths for specific IDs” setting appears to do nothing. Cause: your Google tag is deployed via a web GTM container, and that setting only applies when gtag.js is placed directly in the page source. Fix: rely on the “Default GA4 paths” for event collection; use the gtag.js-paths option only when serving gtag.js on-page through the server container URL.
- The very first GA4 hit is sent directly to google-analytics.com instead of your server container. Cause: gtag fetches the transport/
server_container_urlconfiguration remotely, so the initial hit can fire before server routing is applied (a community-documented race, not confirmed on a first-party page). Fix: setserver_container_url(or the transport URL in the Google tag settings) so the server destination is known at load time, and confirm every hit routes through the server subdomain in preview. claimRequest()throws at runtime. Cause: it was called outside a client (in a tag or variable) or after the client already returned (e.g. inside arunContaineronCompleteasync callback). Fix: callclaimRequest()synchronously at the top of the client template, before it returns — not in deferred callbacks.
Quick recipes
Wire the web page to the server container:
// On-page gtag config: route GA4 traffic to the server containergtag('config', 'TAG_ID', { 'server_container_url': 'https://analytics.example.com'});Minimal custom client that claims one endpoint:
// Sandboxed client template. Claim synchronously, before the client returns.const claimRequest = require('claimRequest');const getRequestPath = require('getRequestPath');const runContainer = require('runContainer');const returnResponse = require('returnResponse');
const path = getRequestPath(); // server_container_url prefix + query strippedif (path !== '/my-endpoint') { return; // no match: let a lower-priority client try to claim}
claimRequest(); // once claimed, no further clients run for this request
const event = { /* build Common Event Data from the request */ };runContainer(event, () => { returnResponse(); // flush: HTTP 200, empty body, no headers by default});Return a tracking-pixel response:
const setPixelResponse = require('setPixelResponse');const returnResponse = require('returnResponse');
setPixelResponse(); // 1x1 GIF with caching + content-type headersreturnResponse(); // flush the queued responseParse an incoming Measurement Protocol V2 request into events:
const isRequestMpv2 = require('isRequestMpv2');const extractEventsFromMpv2 = require('extractEventsFromMpv2');const claimRequest = require('claimRequest');const runContainer = require('runContainer');const returnResponse = require('returnResponse');
if (!isRequestMpv2()) return; // not MPv2: do not claim
claimRequest();const events = extractEventsFromMpv2(/* arguments per the API reference */);events.forEach((event) => runContainer(event, () => {}));returnResponse();Read event data inside a client:
const getAllEventData = require('getAllEventData');const getEventData = require('getEventData');const getClientName = require('getClientName');
const all = getAllEventData(); // a copy of the event dataconst value = getEventData('some.nested.key'); // value at a dot-notation pathconst client = getClientName(); // the current client's nameRelated
Sources
Official Google pages these values were read from (read 2026-07-20):
- An introduction to server-side tagging (read 2026-07-20)
- Send data to server-side Tag Manager (read 2026-07-20)
- Send data to server-side Tag Manager (gtag option) (read 2026-07-20)
- Server-side tagging APIs (read 2026-07-20)
- Configuring the GA4 data stream with server-side tagging (read 2026-07-20)
- Google Ads conversions (server-side) (read 2026-07-20)
- Server-side tagging (overview) (read 2026-07-20)
The five-client enumeration, the “runs the container” distinction, the “cannot
add clients from the template gallery” note, and the single-client priority 0
recommendation are corroborated by practitioner sources rather than a single
official Google list, and are attributed above:
- Making the Move to Server-Side GTM Part Two: What Is a Client? — Adswerve (read 2026-07-20)
- What are clients, requests, transformations, tags, triggers, variables and event data in sGTM — Stape (read 2026-07-20)
- Server-side client configuration demystified — InfoTrust (read 2026-07-20)
- No Client Claimed the Request in sGTM — DumbData (read 2026-07-20)
Things the official documentation does not settle, flagged rather than guessed:
the shipped default Priority numbers of the built-in clients are not stated on
the official pages (only the “higher numbers run first” rule is); the complete
verbatim list of paths the GA4 client claims is only partially confirmed, and
/gtag/destination could not be confirmed on an official page; the dedicated
server-side GA4 tag reference page returned HTTP 404, so the GA4 tag’s exact
forwarding endpoint is drawn from the ads-setup page and third parties rather
than a dedicated tag reference; the current deprecation status of the Universal
Analytics client was not re-verified on a fetched official page (UA collection
has been discontinued by Google in general); and the “first hit bypasses the
server endpoint” mechanism is community-documented, not confirmed on a
first-party Google page.
Changelog
- — Initial version, verified against official documentation.