Skip to main content

Container setup

Every server-side event uses the same foundation: a client-side tag that carries the event to your server, a GA4 Client that receives it, and a custom tag template that calls the Positive User API. Set these up once. Each event page then only adds its own parameters and tag code.

Step 1: configure the client-side GA4 tag​

The client-side tag's only job is to transport event data to your server container. Use a Google Analytics: GA4 Event tag for each event you send.

  1. Set the event name to the event you're tracking (for example purchase).
  2. Point the tag at your server container by setting the server container URL parameter to your server-side endpoint (for example https://sst.yourdomain.com).
  3. For e-commerce events, enable Send Ecommerce Data with the source set to Data Layer. This is what makes the items array reach the server. Without it, item data never arrives.
  4. Trigger the tag on the matching data layer event.

Every event sends these base parameters:

ParameterValue (example)Purpose
server_container_urlhttps://sst.yourdomain.comRoutes the hit to the server container
user_idthe contact's emailContact identifier (see Key decisions)

Each event page lists the extra parameters that event needs.

If you identify by email, you can also send it as a user property named email. The server-side code reads the identifier from several possible locations for robustness.

Where the data arrives

Where items live in your data layer (for example ecommerce.items or a nested structure) is not necessarily where they arrive on the server. GA4 normalizes the ecommerce payload and delivers items at the top level of the event. The server-side code in this guide reads them defensively from both locations.

Step 2: create the server-side GA4 Client​

In your server-side container, make sure a Google Analytics: GA4 client exists. This client receives the request sent by the client-side tag and exposes its data to your tags through the event data.

A default GA4 client with standard settings is enough. No special configuration is required beyond having it enabled.

Step 3: tag template conventions​

Each event gets its own custom tag template in the server-side container (Templates → Tag Templates → New). All templates in this guide share the same fields and permissions.

Fields tab​

Add two text fields so credentials are not hardcoded:

  • apiKey, display name "API Key"
  • subdomain, display name "Workspace Subdomain"

Permissions tab​

The sandbox blocks anything not explicitly allowed. Set these three permissions:

  • Read Event Data, access: Any
  • Send HTTP Requests, allowed URL pattern: https://*.user.com/*
  • Logs to console, environment: All (needed for debugging in Preview)

API requests​

Every template calls the Positive User public API with the same base URL and headers:

const base = 'https://' + data.subdomain + '.user.com/api/public';
const headers = {
'Authorization': 'Token ' + data.apiKey,
'Accept': '*/*; version=2',
'Content-Type': 'application/json'
};

Step 4: test before publishing​

Run both Preview modes at once: the client-side Preview on your website, and the server-side Preview on your server container. They pair automatically because the client-side tag sends to your server URL.

The fastest way to fire a test is a manual data layer push in the browser console, with the page open in Preview. Each event page includes a ready-to-paste test push and the console output of a correct run.

In the server-side Preview, open the event and check the Console tab for the tag's log lines.

Confirm in Positive User

A 2xx status in GTM only means the API accepted the request. The final confirmation is always the record in Positive User itself: open the contact and check that the data was stored.

When everything checks out, publish the server-side container (and the client-side container if you changed it).