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 sendHttpRequest to 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/collect are confirmed for “Default GA4 paths” and /gtag/js?id=TAG_ID for the loader; /gtag/destination could 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

  1. 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 from server_container_url, and verify the path and method match the client’s Activation Path.
  2. 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.
  3. 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.
  4. 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.
  5. The very first GA4 hit is sent directly to google-analytics.com instead of your server container. Cause: gtag fetches the transport/server_container_url configuration remotely, so the initial hit can fire before server routing is applied (a community-documented race, not confirmed on a first-party page). Fix: set server_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.
  6. 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 a runContainer onComplete async callback). Fix: call claimRequest() 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:

gtag-server-config.js
// On-page gtag config: route GA4 traffic to the server container
gtag('config', 'TAG_ID', {
'server_container_url': 'https://analytics.example.com'
});

Minimal custom client that claims one endpoint:

minimal-client.js
// 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 stripped
if (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:

pixel-response.js
const setPixelResponse = require('setPixelResponse');
const returnResponse = require('returnResponse');
setPixelResponse(); // 1x1 GIF with caching + content-type headers
returnResponse(); // flush the queued response

Parse an incoming Measurement Protocol V2 request into events:

mpv2-client.js
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:

read-event-data.js
const getAllEventData = require('getAllEventData');
const getEventData = require('getEventData');
const getClientName = require('getClientName');
const all = getAllEventData(); // a copy of the event data
const value = getEventData('some.nested.key'); // value at a dot-notation path
const client = getClientName(); // the current client's name

Sources

Official Google pages these values were read from (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:

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.

dataLayer

0 events · 0 sent

    • home /
      writing /writing
      guides /guides
      work /#work
      about /about
      colophon /colophon
      toggle analyst mode ctrl+.
      print session receipt /#receipt