The Google Tag Manager Server Side API is a set of JavaScript functions you use inside custom templates to process events, manipulate data, and interact with external services. It runs on your server, not in the user's browser. This allows you to filter out bots, enrich data with server-side information, and send clean signals to platforms like Google Analytics 4 and Meta. You access these functions using the require() method in the custom template editor. This guide explains how to find the right API, read the documentation, and write your first custom template.
Why is your current setup missing the server side API?
Many marketers assume that once a server container is deployed, the magic happens automatically. It does not. The standard tags in your container are pre-built. If you need to do something specific, like removing a specific parameter before sending data to a third party, or checking if a user is a logged-in member of your site before firing a conversion, you need the API.
The API is the bridge between the raw HTTP request hitting your server and the structured data your analytics tools expect. Without it, you are limited to what the pre-built tags allow. With it, you have full control over the logic.
How the architecture works
When a user interacts with your website, the browser sends a request to your server container. This request contains data about the user, the page, and the event. The server container receives this data. It then runs your tags.
If you are using a standard tag, like the GA4 Configuration Tag, it processes the data and sends it to Google. But if you are using a custom template, you are writing the code that processes the data. The Server Side API provides the tools to do that.
You do not write raw Node.js code in the template editor. You write JavaScript that calls the provided APIs. For example, to get the user's IP address, you do not write request.ip. You use the get API to retrieve the data from the request object.
The core APIs you will actually use
The documentation lists many APIs. You do not need to memorize all of them. You need to know where to find them and which ones cover 90% of use cases. The official documentation is at developers.google.com/tag-platform/tag-manager/server-side/api.
Here are the most critical categories:
- Data Access: These APIs let you read data from the incoming request.
get: Retrieves a value from the data object.getCookie: Reads a specific cookie from the request.getParameter: Gets a URL parameter.
- Transformation: These APIs let you modify data before sending.
set: Updates a value in the data object.remove: Deletes a key from the data object.clone: Creates a copy of an object so you can modify it without affecting the original.
- Request Handling: These APIs let you send data out.
httpRequest: Sends an HTTP request to an external URL. This is how you talk to other APIs.formPost: Sends a form-encoded request.
- Utility: Helpers for common tasks.
logTo: Writes to the console for debugging.isDefined: Checks if a value exists.isFunction: Checks if a value is a function.
Finding the right function
When you are building a template, you will type require( in the code editor. The editor will show you a list of available APIs. If you are looking for a specific function, like httpRequest, you can search for it in the documentation.
The key is to read the "Syntax" and "Examples" sections for each function. The syntax tells you what arguments to pass. The examples show you how to use it in context.
For example, if you want to send data to a third-party server, you need httpRequest. The syntax is:
const httpRequest = require('httpRequest');
httpRequest({
method: 'POST',
url: 'https://api.example.com/endpoint',
body: JSON.stringifiedData
}).then((response) => {
logTo('Request sent', response.status);
}).then(() => {
returnResponse();
});
Notice the returnResponse() call. This is crucial. It signals to the server that the tag has completed and the response can be sent back to the client. If you do not call this, the request may hang.
Building your first custom template
To use the API, you need to create a custom template. This is where you write your code.
- Go to your Google Workspace and open Google Tag Manager.
- Navigate to Admin > Templates.
- Create a new template. You can start from a basic template or a blank one.
- In the Edit Code section, you will see a default template. Delete the content inside the
<script>tags. - Start writing your code.
Here is a simple example. This template logs the user's IP address and then sends a response.
const logTo = require('logTo');
const get = require('get');
const returnResponse = require('returnResponse');
const ip = get('event.ip');
logTo('User IP: ' + ip);
returnResponse();
This is a minimal example. In a real scenario, you would be doing more. You might be transforming the data, checking for specific conditions, or calling an API.
The important thing is to understand the flow. The code executes top to bottom. If you use an asynchronous function like httpRequest, you need to handle the callback or Promise. You cannot just call returnResponse() immediately after httpRequest because the request has not yet been sent.
Debugging your code
The best way to debug is to use the Preview mode in Google Tag Manager. Connect your browser to the preview session. Then, trigger the tag on your website.
Look at the Tags Fired section. You will see the console logs. If your code throws an error, it will show up here.
If you are using httpRequest, you can log the response status. This helps you know if the external API is returning a 200 (OK) or a 500 (Server Error).
httpRequest({
method: 'GET',
url: 'https://api.example.com/status'
}).then((response) => {
logTo('Status: ' + response.status);
logTo('Data: ' + JSON.stringify(data.data, null, 2));
}).then(() => {
returnResponse();
});
If you see an error, check the syntax. A missing parenthesis or a typo in the function name will break the code. The error message will tell you the line number.
Connecting to Meta Conversions
One of the most common use cases for the server-side API is connecting to the Facebook Conversions API. This is because the Conversions API requires a server-to-server connection.
Meta has provided a template for this, but you can also build your own. The key is to send the event data to the Conversions Endpoint.
- Get your System User ID and Access Token from your business settings.
- Construct the request body. It needs to include the event name, event time, and user data.
- Send the request using
httpRequest.
const httpRequest = require('httpRequest');
const get = require('get');
const logTo = require('logTo');
const returnResponse = require('returnResponse');
const eventName = get('event.name');
const eventId = get('event.id');
const body = {
data: [{
event_name: eventName,
event_time: Math.floor(Date.now() / 1000),
event_id: eventId,
action_source: 'website',
user_data: {
client_ip_address: get('event.ip'),
client_user_agent: get('event.userAgent')
}
}]
};
httpRequest({
method: 'POST',
url: 'https://graph.facebook.com/v19.0/<PAGE_ID>/events',
body: JSON.stringify(body),
params: {
access token: 'YOUR_ACCESS_TOKEN'
}
}).then((response) => {
logTo('Meta response: ' + response.status);
}).then(() => {
returnResponse();
});
This is a simplified version. In production, you need to handle errors, deduplicate events, and respect privacy regulations. You should always hash the user data before storing or transmitting it.
If you are not sure if your server container is set up to receive these requests, you can use this [Google Tag Manager checker to see if your server-side container is active and firing events]. It will show you if the server is responding and if the events are being processed.
Handling data and performance
When you use the server-side, you are sending more data to your server. This means you need to be mindful of performance.
- Keep templates lightweight: Do not do unnecessary calculations. If you only need the event name, do not retrieve the entire user object.
- Batch your requests: If you are making multiple
httpRequestcalls, consider batching them. This reduces the number of outbound requests. - Set timeouts: Always set a timeout for your HTTP Requests. If the external server is down, you do not want your server to wait indefinitely.
httpRequest({
method: 'GET',
url: 'https://api.example.com/data',
options: {
timeout: 5000 // 5 seconds
}
}).then((response) => {
// Handle response
}).catch((error) => {
logTo('Request failed: ' + error.message);
}).then(() => {
returnResponse();
}).catch(() => {
returnResponse();
}).done();
The .catch() blocks are essential. They ensure that even if the request times out or the server returns an error, your tag still completes and the response is sent.
Security and best Practices
Security is critical when you are working with server-side code.
- Never hardcode secrets: Do not put your access tokens in the code. You should store them in environment or secrets. Google Tag Manager does not have a direct secrets manager for custom templates, so you need to be careful. One common workaround is to use a server-side variable that is populated from a secure source.
- Validate input: Always check the data you receive from the client. Do not assume it is clean. A malicious user could send bad data.
- Log responsibly: Do not log sensitive data like email or phone numbers. You are creating a log file that could be accessed.
If you are building a complex system, you might want to consider using a middleware. This is a separate service that sits between your server container and the third-party APIs. It handles the authentication and data transformation. This way, your custom templates remain simple.
For most small to mid-sized businesses, building the custom template directly in Google Tag Manager is fine. But if you have many endpoints or complex business rules, a middleware might be worth the cost.
You can learn more about building robust tracking systems in our server-side tracking services. We help businesses set up these systems securely and efficiently.
Conclusion
The Google Tags Manager Server Side API is a power tool. It gives you control over your data and your tracking. It allows you to do things that are not possible with client-side tagging.
Start small. Build a simple template that logs data. Then add complexity. Use the preview mode to debug. Read the official docs for every function you use.
The key is to understand the request/response lifecycle. Your code runs on the server. It receives data, processes it, and sends a response. If you keep that in mind, you will not get confused.
The server-side is not just a place to put tags. It is a place to build logic. Use it to clean your data, enrich your events, and connect to the services that matter.
If you want to see what a well-built server-side tracking setup can do for your business, check out our work portfolio to see real-world examples of automated lead systems. We build these systems for coaches and small business every day.
For more on how to structure your data, read our guide on how to add data in Google Analytics 4.
And if you need help with your setup, contact us to discuss your specific needs. We can audit your current setup and tell you where you are losing data.