---
id: "integrations/attribution/google-tag-manager"
title: "Google Tag Manager"
description: "This article shows you how to load a Google Tag Manager (GTM) container on published RevenueCat Funnels. By the end, you'll have production and sandbox container IDs saved in Integrations. Published funnels load those containers and send funnel step and purchase events that you can map in GTM Preview."
permalink: "/docs/integrations/attribution/google-tag-manager"
slug: "google-tag-manager"
version: "current"
original_source: "docs/integrations/attribution/google-tag-manager.mdx"
---

> **AI agents:** This is the Markdown version of a RevenueCat documentation page. For the complete documentation index, see [llms.txt](https://www.revenuecat.com/docs/llms.txt).

This article shows you how to load a Google Tag Manager (GTM) container on published [RevenueCat Funnels](https://www.revenuecat.com/docs/tools/funnels). By the end, you'll have production and sandbox container IDs saved in Integrations. Published funnels load those containers and send funnel step and purchase events that you can map in GTM Preview.

:::info[Subscription events]
RevenueCat doesn't send renewals, trial conversions, or other subscription lifecycle events into GTM. Funnel step and purchase events fire in the browser. For server-to-server funnel events, use [Funnel Integrations](https://www.revenuecat.com/docs/tools/funnels/integrations).
:::

## Setup

### 1. Create a GTM container

Create a web container in Google Tag Manager, or use an existing one. The container ID looks like `GTM-XXXXXXX`. Copy it from the top of the GTM workspace.

Use a separate container for sandbox if you want test traffic isolated from production tags.

### 2. Add the container ID in RevenueCat

1. Open your project in the RevenueCat dashboard.
2. In the lower-left corner, select **Integrations**.
3. Select **Google Tag Manager**.
4. Enter the **Container ID**. Production published funnels load this container.
5. Optionally enter a **Sandbox Container ID**. Sandbox published funnels load that ID. If it's empty, sandbox funnels don't load GTM.
6. Save.

The container loads on the first step so tags can store the ad click identifier from the landing URL.

### 3. Confirm the container in GTM Preview

1. Publish the funnel.
2. In your GTM workspace, open **Preview** and connect to the published funnel URL.
3. Walk the funnel. In the Preview summary, confirm the container loads on the first step. Then confirm `rc_workflow_step_started_event`, `rc_workflow_step_completed_event`, and `rc_workflow_purchase_event` as you complete steps and check out.

:::info[Custom domain for Google Ads]
Google stores the ad click identifier in a first-party cookie on the funnel hostname. Use a [custom domain](https://www.revenuecat.com/docs/tools/funnels/deploying-funnels#custom-domains) so attribution isn't lost when a Customer visits other funnels that share the same cookie.
:::

## Map funnel events in GTM

These `dataLayer` event names are fixed. They can't be changed in RevenueCat.

Each published funnel is client-side routed, so GTM's built-in Page View trigger fires once. Use these events as triggers for each step. Don't rely on History Change or the built-in Page View trigger for step transitions.

| Event | When it fires |
| :---- | :------------ |
| `rc_workflow_step_started_event` | A Customer views a funnel step |
| `rc_workflow_step_completed_event` | A Customer completes a funnel step |
| `rc_workflow_non_checkout_completion_event` | A Customer ends the funnel through a configured exit without a purchase |
| `rc_workflow_purchase_event` | A Customer completes a purchase |

`rc_workflow_purchase_event` fires once. Refreshing the success page doesn't send it again.

### Event properties

These properties are on each `dataLayer` event. Use them in GTM triggers and variables. For example, fire a "Paywall Viewed" tag on `rc_workflow_step_started_event` when `is_paywall` is `true`.

Classification flags are `true` on the current step when that classification applies. Each event also clears the other known `is_*` keys and `step_name` so GTM does not keep the previous step's values in a single-page funnel. In GTM, trigger on the flag being `true`. These events don't include a `screen_type` array or a `step_type` string.

:::info[Republish existing funnels]
Republish existing funnels so `step_name` and the `is_*` flags appear in GTM. Funnels published before step `name` and `screen_type` were added to the published JSON don't include them.
:::

| Property | Events | Description |
| :------- | :----- | :---------- |
| `workflow_id` | Step started, step completed, non-checkout completion | Funnel ID |
| `step_id` | Step started, step completed, non-checkout completion | Current step ID |
| `step_name` | Step started, step completed, non-checkout completion | Editor step name, when present |
| `from_step_id` | Step started | Previous step ID, when the Customer navigated from another step |
| `is_first_step` | Step started, step completed | `true` on the funnel's initial step |
| `is_last_step` | Step started, step completed | `true` on a terminal step |
| `is_paywall` | Step started, step completed, non-checkout completion | Present as `true` when the step is classified as a paywall |
| `is_checkout` | Step started, step completed, non-checkout completion | Present as `true` when the step is classified as checkout |
| `is_authentication` | Step started, step completed, non-checkout completion | Present as `true` when the step is classified as authentication |
| `is_initial` | Step started, step completed, non-checkout completion | Present as `true` when the step is classified as the initial screen |
| `is_success` | Step started, step completed, non-checkout completion | Present as `true` when the step is classified as success |
| `is_redirect` | Step started, step completed, non-checkout completion | Present as `true` when the step is classified as a redirect |
| `is_second` | Step started, step completed, non-checkout completion | Present as `true` when the step is classified as the second screen |
| `entry_reason` | Step started | Why this step started, for example `navigation` |
| `experiment_id` | Step started, step completed, non-checkout completion | Experiment ID when the step is in an experiment |
| `experiment_variant` | Step started, step completed, non-checkout completion | Enrolled variant when the step is in an experiment |
| `value` | Purchase | Purchase amount |
| `currency` | Purchase | ISO currency code |
| `transaction_id` | Purchase | Checkout operation session ID, used to deduplicate conversions |

## Next steps

[Deploy the funnel](https://www.revenuecat.com/docs/tools/funnels/deploying-funnels) so published pages load the container.

For server-to-server funnel events, see [Funnel Integrations](https://www.revenuecat.com/docs/tools/funnels/integrations).
