> For the complete documentation index, see [llms.txt](https://doc.batch.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://doc.batch.com/developer/technical-guides/how-to-guides/web/how-to-send-data-from-a-gtm-server-side-container-to-batch.md).

# How to send data from a GTM Server-Side container to Batch?

Google Tag Manager Server-Side (sGTM) lets you collect events on your website via a lightweight client-side snippet and forward them to your own server container before redistributing them to downstream tools. This guide explains how to route those events to Batch using the Profile API.

{% hint style="info" %}
The connection between your sGTM container and Batch must be implemented by your technical team using a custom HTTP Request tag.
{% endhint %}

### Prerequisites

Before you start, make sure you have:

* A Google Tag Manager Server-Side container deployed on a first-party subdomain (e.g. `collect.yourdomain.com`).
* The Batch **REST API Key** and **Project Key** for your project (available in your Batch dashboard).
* The Batch `installation_id` and/or `custom_id` exposed in your `dataLayer` at the time events are triggered.

***

### Step 1: Expose the Batch identifier in the dataLayer

The Profile API requires an identifier to target the correct Batch profile. Both options below run **client-side, in the page** — not inside the sGTM container. The sGTM container reads these values from the `dataLayer` via Data Layer Variables (see Step 2).

**Option A — Custom User ID (authenticated users)**

The `custom_id` comes from your own authentication system. Push it to the `dataLayer` when the user logs in or when the page loads for an authenticated session.

The value must be the same stable identifier you use to identify users in your systems (login ID, hashed email, etc.).

**Option B — Installation ID (anonymous users)**

The Batch Web SDK generates an `installation_id` automatically. Retrieve it client-side using the SDK and push it to the `dataLayer`:

```js
// Run client-side, after the Batch SDK has initialized
batchSDK(function(api) {
  api.getInstallationID().then(function(installationId) {
    window.dataLayer = window.dataLayer || [];
    window.dataLayer.push({ batch_installation_id: installationId });
  });
});
```

{% hint style="warning" %}
Both snippets must execute client-side, in the browser, before any sGTM event fires. Push the identifier as early as possible in the page lifecycle to ensure it is available for all subsequent events captured by the sGTM container.
{% endhint %}

***

### Step 2: Create the dataLayer variables in your sGTM container

In your sGTM container, create **Data Layer Variable** variables to read the identifiers you pushed in Step 1.

1. Go to **Variables** > **New**.
2. Select **Data Layer Variable** as the variable type.
3. Set the **Data Layer Variable Name** to `custom_id` (repeat for `installation_id` if needed).
4. Save the variable.

Repeat this step for any event attributes you want to forward to Batch (e.g. `ecommerce.value`, `event`, etc.).

***

### Step 3: Create the custom HTTP Request tag

1. In your sGTM container, go to **Tags** > **New**.
2. Select **HTTP Request** as the tag type.
3. Configure the tag as follows:

**Request URL**

```
https://api.batch.com/2.11/profiles/update
```

**Method**: `POST`

**Headers**

| Key               | Value                           |
| ----------------- | ------------------------------- |
| `Content-Type`    | `application/json`              |
| `Authorization`   | `Bearer {{Batch REST API Key}}` |
| `X-Batch-Project` | `{{Batch Project Key}}`         |

{% hint style="warning" %}
Store your REST API Key as a **Constant** variable with **type: Secret** in your sGTM container. Never expose it in client-side code.
{% endhint %}

**Request Body**

Build the JSON body dynamically using your sGTM variables. The structure depends on whether you identify users by `custom_id` or `installation_id`.

With a Custom User ID:

```json
[
  {
    "identifiers": {
      "custom_id": "{{batch_custom_id}}"
    },
    "attributes": {
      "your_attribute": "{{your_variable}}"
    },
    "events": [
      {
        "name": "{{event_name}}",
        "attributes": {
          "$label": "{{event_label}}"
        }
      }
    ]
  }
]
```

With an Installation ID:

```json
[
  {
    "identifiers": {
      "installation": {
        "apikey": "{{Batch API Key}}",
        "installation_id": "{{batch_installation_id}}"
      }
    },
    "events": [
      {
        "name": "{{event_name}}"
      }
    ]
  }
]
```

4. Save the tag.

***

### Step 4: Set the trigger

Configure the tag to fire on the events you want to forward to Batch (e.g. `purchase`, `add_to_cart`, `page_view`).

1. In the tag settings, click **Triggering**.
2. Select an existing trigger or create a new one based on the event name.
3. Save.

***

### Step 5: Test and publish

1. Use the **Preview** mode in GTM to verify the tag fires correctly on the expected events.
2. Check that the HTTP request reaches the Batch API and returns a `202` response.
3. Verify that the profile is updated in the Batch dashboard.
4. Once validated, publish your sGTM container.

***

### Notes

* If both `custom_id` and `installation_id` are available, prefer `custom_id` to ensure correct profile stitching across channels.
* For more details on the available fields, constraints and rate limits, see the [Profile API reference documentation](https://doc.batch.com/developer/api/cep/profiles/update).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://doc.batch.com/developer/technical-guides/how-to-guides/web/how-to-send-data-from-a-gtm-server-side-container-to-batch.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
