# Google Analytics 4 Proxy Reference

{% hint style="info" %}
This is a Proxy Integration for GA4. This destination runs on Freshpaint's servers, but emulates a native installation of GA4. That means the integration behaves the same as if you did a native installation of GA4, but the data first flows through Freshpaint before it's sent to GA4. [See our docs on proxy integrations for more information](https://documentation.freshpaint.io/reference/faqs/what-is-a-proxy-integration).
{% endhint %}

Google Analytics 4 is an analytics service that enables you to measure traffic and engagement across your websites and apps.

After sending Freshpaint data to Google Analytics 4, you'll be able to analyze the data in order to identify trends and patterns in how visitors engage with your website(s).

Learn more about Google Analytics 4 [here](https://support.google.com/analytics/answer/10089681).

## Destination Info

* Accepts [Track](https://documentation.freshpaint.io/developer/freshpaint-sdk-reference#track) and [Identify](#identify) calls
* Refer to this destination as **Google Analytics 4 Proxy** in the [Integrations object](https://documentation.freshpaint.io/reference/developer/freshpaint-sdk-reference#using-the-integrations-object)
  * If you've configured multiple Measurement IDs, you can choose a specific one by suffixing the Measurement ID, such as: **Google Analytics 4 Proxy::G-PSW1MY7HB4.** You can retrieve this value from the Google Analytics 4 (Proxy) configuration page for the Measurement ID of interest. &#x20;
  * For other considerations when using multiple Google Analytics 4 Proxy Measurement IDs, see [google-analytics-4-proxy-multi-config-reference](https://documentation.freshpaint.io/integrations/destinations/apps/google-analytics-4-proxy/google-analytics-4-proxy-multi-config-reference "mention").

{% hint style="info" %}
When no suffix is specified, all configured Measurement IDs are selected for inclusion / exclusion.
{% endhint %}

* Connection Modes:

<table><thead><tr><th> </th><th data-type="checkbox">Client-side</th><th data-type="checkbox">Server-side (Proxy)</th></tr></thead><tbody><tr><td>Web</td><td>false</td><td>true</td></tr><tr><td>Mobile</td><td>false</td><td>true</td></tr><tr><td>Server</td><td>false</td><td>true</td></tr></tbody></table>

## Events

All events will be sent to GA4 from Freshpaint's servers. Your website will not send data directly to GA4. Instead, your website and all other sources will send data to Freshpaint, which is translated then sent to GA4.

Events sent from Freshpaint to GA4 will show up as standard GA4 events. From there you can use your events in any of the GA4 reports and use it to generate insights into your business.

### Page View Events

Freshpaint will automatically send a `page_view` event to Google Analytics. This page view event will behave the same as the native Google Analytics `page_view` event.

Manually sending a page view event to Freshpaint by calling [freshpaint.page()](https://documentation.freshpaint.io/developer/freshpaint-sdk-reference#page) is not currently supported.

{% hint style="info" %}
If you have a requirement to have more granular control of which page views should be sent to GA4, you can choose to disable the **Send Page View** option and create a custom`page_view` event that only triggers on the pages you want to send to GA4 instead.
{% endhint %}

### Session Start

Freshpaint will automatically send a `session_start` event to Google Analytics. A new session is created for a user if the user performs an action after 30 minutes of inactivity.

### Engagement Time

Freshpaint will automatically send engagement time to GA4 and populate the engagement time reports in GA4.&#x20;

Seeing user engagement discrepancies from a native GA4 implementation? See the article [here](#user-engagement-discrepancies) for more information on this topic.

### Scroll

Freshpaint will automatically `scroll` events to GA4.

### Video Engagement

Freshpaint can be optionally enabled to send `video_start`, `video_progress`, and `video_complete` events to GA4. This includes videos hosted on [Freshpaint's Video Platform](https://documentation.freshpaint.io/integrations/freshpaint-video-platform).

Enable the `Send Video Engagement Event` option in the GA4 destination Base Configuration settings to turn on sending Video events to GA4. The recommended property `$video_event_type` must be allowlisted for video engagement events to be forwarded. Additionally, you can also allowlist these contextual video properties: `video_current_time`, `video_duration`, `video_percent`,  `video_provider`, `video_title`, and `video_url`.

The current version of Freshpaint will only track video progress on YouTube videos embedded on a page using the [YouTube JavaScript API](https://developers.google.com/youtube/iframe_api_reference) or Freshpaint Video Platform videos embedded as IFrames. Other video providers may be supported in the future.

### Conversions

Freshpaint is able to send conversion events to GA4. For this to work, there are two necessary steps:

1. Using an existing event, or after creating a new event, you must mark that event as a conversion in GA4's dashboard.
2. You must include a property named `"conversion"` and set it to `true` in your event. You can do this with a direct call to [freshpaint.track()](https://documentation.freshpaint.io/reference/developer/freshpaint-sdk-options), or you can do this as a [transformation](https://documentation.freshpaint.io/admin-panel/transformations). If you're using the [Google Tag Manager Integration](https://documentation.freshpaint.io/integrations/google-tag-manager-integration), you should set the `conversion` property on the Freshpaint GA4 tag.

{% hint style="warning" %}
If your account is in HIPAA mode, then you must add `conversion` to your HIPAA allowlist, unhashed. If you don't allow `conversion`, then GA4 will not be able to see the property it needs to consider your event a conversion.
{% endhint %}

You can find the interface in GA4 that lets you mark events as conversions at Admin > Events, where the link is below the property you're looking to measure events:

<figure><img src="https://1666823438-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MA7aDqsXMFbUsWVqonF%2Fuploads%2FG5UImqTsi2PWY7e8WwQe%2Fga4-event-conversions.png?alt=media&#x26;token=510ff912-20c0-4876-908b-666de8400eef" alt=""><figcaption><p>In this example, the last two events shown are marked as conversions</p></figcaption></figure>

Below is also an example of what a transformation would look like to send the conversion property to GA4 as a constant property:

<figure><img src="https://1666823438-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MA7aDqsXMFbUsWVqonF%2Fuploads%2FohvyzvzdiOXmS4xK86CD%2Fga4-transformation.png?alt=media&#x26;token=6e78e3b2-35fd-4ac5-971b-7890671a6623" alt=""><figcaption></figcaption></figure>

### Purchases

You can send purchase events to GA4. Here is GA4's reference documentation: <https://developers.google.com/analytics/devguides/collection/ga4/reference/events?client_type=gtag#purchase>

From the Freshpaint side, there are a few things you need to know:

Your event name must be `purchase`. You can either create an event named `purchase`, or you can use a transformation to change some other event's name to to `purchase` when sent to the GA4 Proxy destination.

You must include two properties named `currency` and `value`. `currency` should be a three letter currency code - for example, `USD` for US dollar. `value` should be a number which is the purchase price.

Finally, you must include a property named `items`, which is an array of objects that contains properties like the following. Some of these properties are required; if you don't include them, your event may not be recorded as a purchase by GA4.

<table><thead><tr><th>Item Property</th><th data-type="checkbox">Required?</th><th>Description</th></tr></thead><tbody><tr><td><code>item_id</code></td><td>true</td><td>The product ID</td></tr><tr><td><code>item_name</code></td><td>true</td><td>The name of the product</td></tr><tr><td><code>price</code></td><td>false</td><td>How much the item costs according to the currency used</td></tr><tr><td><code>quantity</code></td><td>false</td><td>How many of the item was purchased</td></tr><tr><td><code>item_brand</code></td><td>false</td><td>The brand of the item</td></tr><tr><td><code>item_category</code></td><td>false</td><td>The category of the item. If used as part of a category hierarchy or taxonomy then this will be the first category.</td></tr><tr><td><code>item_category2</code></td><td>false</td><td>The second category hierarchy or additional taxonomy for the item.</td></tr><tr><td><code>item_category3</code></td><td>false</td><td>The third category hierarchy or additional taxonomy for the item.</td></tr><tr><td><code>item_category4</code></td><td>false</td><td>The fourth category hierarchy or additional taxonomy for the item.</td></tr><tr><td><code>item_category5</code></td><td>false</td><td>The fifth category hierarchy or additional taxonomy for the item.</td></tr><tr><td><code>item_variant</code></td><td>false</td><td>The item variant or unique code or description for additional item details/options.</td></tr><tr><td><code>affiliation</code></td><td>false</td><td>A product affiliation to designate a supplying company or brick and mortar store location.</td></tr><tr><td><code>discount</code></td><td>false</td><td>The monetary discount value associated with the item.</td></tr><tr><td><code>coupon</code></td><td>false</td><td>A coupon code, if one was used</td></tr><tr><td><code>item_list_id</code></td><td>false</td><td>The ID of the list in which the item was presented to the user.</td></tr><tr><td><code>item_list_name</code></td><td>false</td><td>The name of the list in which the item was presented to the user.</td></tr><tr><td><code>index</code></td><td>false</td><td>The index/position of the item in a list.</td></tr><tr><td><code>location_id</code></td><td>false</td><td>The physical location associated with the item (e.g. the physical store location). It's recommended to use the <a href="https://developers.google.com/maps/documentation/places/web-service/place-id">Google Place ID</a> that corresponds to the associated item. A custom location ID can also be used.</td></tr><tr><td><code>creative_name</code></td><td>false</td><td>The name of a promotional creative</td></tr><tr><td><code>creative_slot</code></td><td>false</td><td>The name of the promotional creative slot associated with the item.</td></tr><tr><td><code>promotion_id</code></td><td>false</td><td>The ID of the promotion associated with the item.</td></tr><tr><td><code>promotion_name</code></td><td>false</td><td>The name of the promotion associated with the item.</td></tr></tbody></table>

Here's an example event payload that would send a purchase event:

<pre class="language-json"><code class="lang-json">{
  "token": "&#x3C;your-env-id>",
  "time": 1680551282,
  "$device_id": "test-device-id",
  "currency": "USD",
  "value": 123.45,
  "items": [{
    "item_id":       "item 1",
    "item_name":     "my-name",
    "item_brand":    "blammo",
    "item_category": "cool products",
    "item_variant":  "tie-dye",
    "price":    123.45,
    "quantity": 3,
<strong>    "coupon":   "WINTER_FUN",
</strong>    "item_list_name":     "fun list",
    "index": 1,
    "creative_name": "spring sale 1"
  }, {
    "item_id":       "item 2",
    "item_name":     "my-name 2",
    "item_brand":    "blammo",
    "item_category": "cool products",
    "item_variant":  "tie-dye",
    "price":    15,
    "quantity": 1,
    "coupon":   "WINTER_FUN",
    "item_list_name":     "fun list",
    "index": 2,
    "creative_name": "spring sale 2"
  }],
}

</code></pre>

### Identify

An identify call will show up in Google as an "Identify" event. Any user properties sent in the identify call will show up as user properties in Google Analytics.

{% hint style="info" %}
If HIPAA mode is enabled for your account, Freshpaint will redact URL paths by default. To avoid seeing `/url-redacted-by-freshpaint` URL paths in GA4 reporting, you will need to [allowlist](https://app.freshpaint.io/destinations/apps/google-analytics-4-proxy/phiallowlist) both the `URL` and `Pathname` properties under **User Properties** for `Identify` events.
{% endhint %}

### Testing your events

While Google Analytics 4 normally requires you to wait for the next day to see your data shown in reports, it offers a way to quickly test your events in real time. To do that, first head to your account's admin screen, and then click `DebugView`:

<figure><img src="https://1666823438-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MA7aDqsXMFbUsWVqonF%2Fuploads%2Fb9ElI6b5K8lFIyhQNyfF%2Fga4-debug-view.png?alt=media&#x26;token=e2fd991c-2d63-4ff0-8d33-ab205ccfbc2e" alt=""><figcaption></figcaption></figure>

That link takes you to a screen where debug events show up in a real time. To send debug events to GA4, you need to add a property to your events named `"debug_mode"` set to `true`. Here's an example:

```json
{
  "distinct_id": "test-user-id",
  "$device_id": "111222",
  "token": "your-environment-id",
  "time": 1680131903,
  "debug_mode": true,
  "test-property": 10
}
```

You can, for example, send such an event with our [Event Tester](https://documentation.freshpaint.io/admin-panel/events/event-tester). When you submit your event, it will now show up in the DebugView.

Select a device from the Debug Device list to see events tracked in `debug_mode`.

<figure><img src="https://1666823438-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MA7aDqsXMFbUsWVqonF%2Fuploads%2FO3ThYS9jOFiLnOpMNcbv%2Fga4-debugView.png?alt=media&#x26;token=0978f3d0-14d6-4959-8957-29c7a9d04749" alt=""><figcaption></figcaption></figure>

## Making the switch to Google Analytics 4

Google Analytics 4 is fully equipped to support your measurement needs today and into the future. Google will be turning down [Universal Analytics](https://support.google.com/analytics/answer/2790010?hl=en), so it is recommended you to make the switch to Google Analytics 4 as soon as possible. To get help in migrating to GA4, you can refer to Google's docs [here](https://support.google.com/analytics/answer/10759417).

{% hint style="warning" %}
On July 1, 2023, standard Universal Analytics properties will no longer process data. You'll be able to see your Universal Analytics reports for a period of time after July 1, 2023. However, new data will only flow into Google Analytics 4 properties.
{% endhint %}

## Differences Between Native Google Analytics 4 and Freshpaint Google Analytics 4 Proxy

Out of the box there will be some differences between a native Google Analytics 4 integration and a Freshpaint Google Analytics 4 integration. These are currently the following:

* Events sent from Freshpaint to Google Analytics 4 when the destination is in HIPAA mode will only have state-level geolocation information attached to them.
* [Enhanced measurement events](https://support.google.com/analytics/answer/9216061?hl=en) are not configured out of the box. If you have enhanced event measurement enabled, a native Google Analytics integration will capture a number of events out of the box that Freshpaint does not. This includes events such as scroll events and download\_file events. If you are interested in capturing these events, contact <support@freshpaint.io> for assistance in capturing the properties.
* Demographics data is currently not supported.
* An increase in user engagement events is expected after transitioning to Freshpaint. Freshpaint makes continuous effort to emulate Google Analytics' tracking behavior, but strict parity is not possible due to GA4 being closed source. You can read more about this below.
* Reduced Geo-location accuracy for HIPAA customers only - We will reduce the geo-location accuracy to remain in compliance with HIPAA guidance. Google Analytics uses the IP address to geo-locate the user. Freshpaint will replace the IP address of the customer with another IP address within the same State and Country.

{% hint style="info" %}
Analytics that look at City-level or at a more granular level will produce inaccurate results within Google Analytics due to the IP address replacement, however this is necessary in order to remain HIPAA compliant.<br>
{% endhint %}

### User Engagement Discrepancies

An increase in user engagement events is expected after transitioning to Freshpaint. Freshpaint makes continuous effort to emulate Google Analytics' tracking behavior, but strict parity is not possible due to GA4 being closed source. One example of a known difference between the implementations is detailed below:

Freshpaint's approach triggers a **user\_engagement** event each time a user switches tabs, potentially resulting in multiple events for a single session. In contrast, GA4 consolidates engagement time into a single event, sending it only when the user navigates away or closes the tab. Both methods measure total engagement time but differ in event frequency.

There are some situations that may increase the magnitude of the discrepancy. Those include:

1. Modifying the default user\_engagement event within your Google Analytics 4 account. Since this is the event used to determine engagement and bounce rates, changing how this event is defined will change what is being measured, likely leading to a change despite it being the “same” event.
2. Not uninstalling old Google Analytics 4 installations when installing Freshpaint. If GA4 is installed twice, it will send redundant data that may be interpreted by Google Analytics as additional user engagement.

Unfortunately, we can't provide a specific expectation for discrepancies in engagement time or percentage. Since we don't have full visibility into GA4's measurement model, we're unable to directly compare our approach to theirs.&#x20;

If you'd like help in examining a user engagement discrepancy, please contact us at <support@freshpaint.io>&#x20;

## Conversion Event Imports Between Google Analytics and Google Ads

The workflow of importing GA4 events as conversion actions in Google Ads is considered non-compliant, primarily related to the handling of user identifiers like the GCLID (Google Click Identifier).&#x20;

To remain compliant for both GA4 and Google Ads, Freshpaint recommends:

* **Not allowlisting the Google Click Identifier (GCLID) property for your Google Analytics destination.**
* **Creation of net-new Website Conversion Actions in Google Ads**: Instead of passing the GCLID directly to GA4, create specific Website conversion actions. This method generates a "conversion label" which allows Freshpaint to map an event to a specific conversion action in Google Ads.
* **Sending Data to Google Ads**: When sending data to Google Ads, only the GCLID and the conversion label are sent for attribution, using the [Google Ads](https://documentation.freshpaint.io/integrations/destinations/advertising-destinations/google-ads/google-ads-quick-start-guide) or [Google Ads Conversions API](https://documentation.freshpaint.io/integrations/destinations/advertising-destinations/google-ads-conversion-api/google-ads-conversion-api-quick-start-guide) destinations.
* **Unlinking your Google Analytics 4 property from your Google Ads account.** The process for how these 2 tools are unlinked is documented [here](https://support.google.com/analytics/answer/9379420), under the "*Unlinking Google Ads accounts from Analytics*" section of the article.

## Configuration Settings

#### Event Transformations

Set up transformations to modify your data before it's sent to your destination. Read more about transformations [here](https://documentation.freshpaint.io/transformations).


---

# Agent Instructions: 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:

```
GET https://documentation.freshpaint.io/integrations/destinations/apps/google-analytics-4-proxy/google-analytics-4-proxy-reference.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
