Skip to main content
  1. Blog Post/

APP + WEB: Google Analytics Measurement Protocol version 2

6 min · 2324 words
#GA4
Table of Contents

The Google Analytics Measurement Protocol allows users and developers to make HTTP requests directly to Google Analytics endpoint in order to measure how users interact from any enviroment/platform.

Since Google announced the new APP+WEB Properties back in summer, we noticed that the &v parameter that used to hold a fixed 1 value turned to be a =2 value in our hit requests. Which implicitily means that at some point a new version of the Measurement Protocol is going to be released.

I tried to reverse-engineer all the details I could about the parameters used on this new upcoming protocol.

Please have in mind that the , and I'm publishing all the info I was able to gather.

Introduction

The new Measurement Protocol cames with some great new improvements over the version 1 that we're used to see in our Universal Analytics hits.

I'd try to think about this new protocol as an enhanced version of the previous one. They even share some parameters.

What's new on the version 2 protocol

This new measurement protocol seems to had been designed having some performance optimizations in mind.

First thing we need to have in mind is that APP+WEB doesn't longer have "hit types", everything we may end sending to APP+WEB is an "event" that may (or may not) be accompanied with parameters.

There 2 groups of parameters in the APP+WEB Measurement Protocol .
Let's think about them as the event parameters "scope".

    Also the parameters accepts 2 diferente values types:

    Batched Events

    Now by default APP+WEB Protocol allows to send batched events, meaning that with a single hit request we'll be able to send multiple events. I know this is not new at all, and we ever needed to debug an APP implemention we'd have noticed that version 1 protocol allowed us to send batched hits ( via /batch endpoint ).

    In any case v2, comes with some extra enhanced comparted with the legacy version,

      Debugging

      Debugging the new measurument protocol v2 has became even easier, since the new properties offer a Debug View.

      In order to have our hits showing up here, we'll need to add a _dbg=1 parameter to our hits.

      &_dbg=1
                                      

      Then our hits will show up in the DebugView report in real time, making our debugging efforts much easier that they actual are.

      Turning on the debug on the web based library

      If you're working on a website based implementation you can turn on the "oficial" debugging logs just loading the GTAG container with the &dbg={{randomNumber}} parameter:

      https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX&l=dataLayer&cx=c&dbg=918
                                      

      This will turn on the debug output into our browser, giving us a log of detailed info about what's happening.


      Building a request

      APP+WEB hits need to go to a new endpoint that is located on the following URL:

      https://www.google-analytics.com/g/collect
                                      

      As we mentioned in our technical overview for the new APP+WEB Properties now the hits al built in 2 separate parts:

        The Request Payload will only be available when there're more than 1 event on the current hit request. If the hit only contains one event, the parameter will be attached to the QueryString as the rest of the common shared parameters

        The following code will help us to understand how should be build a hit, and also how to send it to APP+WEB Endpoint using the navigator.sendBeacon function.

        // APP+WEB Endpoint
        var endPoint = 'https://www.google-analytics.com/g/collect';
        
        // Base Event Model for Web Hit
        var eventModel = {
            v: 2,
            tid: 'G-XXXXXXXX-0',
            _p: Math.round(2147483647 * Math.random()),
            sr: screen.width + 'x' + screen.height,
            _dbg: 1,
            ul: (navigator.language || "").toLowerCase(),
            cid: '1908161148.1586721292',
            dl: 'https://appweb.thyngster.com/',
            dr: '',
            dt: 'APP + WEB Measurement Protocol version2 DEMO',
            sid: new Date() * 1,
            _s: 1
        }
        
        // A queue to batch our events
        var events = [];
        
        var requestQueryString;
        var requestBody;
        
        // Let's push some events 
        events.push({
            'en': 'pageview'
        });
        // Second Event
        events.push({
            'en': 'scroll',
            '_et': '5000',
            'epn.percent_scrolled': '90'
        });
        // Another more event
        events.push({
            'en': 'useless_no_bounce_event',
            '_et': '5000',
            'ep.no_bounce_time': '5sec'
        });
        
        // Is there any event in our queue?
        if (events.length > 0) {
            // If there's only one event, we'll not pushing a body within our request
            if (events.length === 1) {
                Object.assign(eventModel, events[0]);
            } else {
                requestBody = events.map(function(e) {
                    return (Object.keys(e).map(key=>key + '=' + e[key]).join('&'));
                }).join("\n");
            }
            requestQueryString = Object.keys(eventModel).map(key=>key + '=' + encodeURIComponent(eventModel[key])).join('&');
            navigator.sendBeacon(endPoint + '?' + requestQueryString, requestBody);
        }
                                        

        Parameters Reference

        Request Parameters

        These parameters are available across all hits. There are related to the current hit.

        ParameterValue TypeValue
        vintProtocol Version
        tidstringStream ID ( G-XXXXXXXXX )
        cidstringClient ID Value
        sidstringSession ID . ( current session start TimeStamp )
        srstringScreen Resolution
        _dbgboolDebug Switch
        ulstringUser Language
        _fid
        _ucibool
        _p
        gtmstringContainer Hash
        _sintegerSession Hits Count

        Shared Parameters

        ParameterValue TypeValue
        dlstring (url)Document Location
        drstring (url)Document Referer
        dtstringDocument Title
        sidstringSession ID
        sctintegerSession Count
        segbooleanSession Engagement
        _fvboolFirst Visit
        _nsiboolNew Session Id
        _ssboolSession Start
        custringCurrency Code
        _c

        Event Parameters

        ParameterValue TypeValue
        enstringEvent Name
        _etintegerEvent Time
        up.*stringUser Parameter String
        upn.*numberUser Parameter Number
        ep.*stringEvent Parameter String
        epn.*numberEvent Parameter Number

        Ecommerce

        NOTE: I want to add that this was live on the latest gtag version one week ago, and that it seems it has been removed. In any case I wouldn't expect to have changes on the final release.

        We're splitting the parameters related to the Ecommerce on 3 categories. We need to have in mind that APP+WEB have 2 main groups of models for the Enhanced Ecommerce, the Products Model and the Promotions Model.

        Products Model, is used in every single ecommerce event that is sent to Google Analytics . Which includes product listings, products clicks, product details views, products adds to cart, products remove from cart, product checkout, products purchases and products refunds.

        Promotions Model, this is the second model, this is for the promotions tracking in the Enhanced Ecommerce, since they're not directly related to a product this is a total aside model used on APP+WEB

          Product Items

          Products Items are send under it's own incremental key, &pr1, &pr2 ... &prN . Then each of these parameters will hold all the product model info.

          Example:

          &pr1': 'idP12345~nmAndroid Warhol T-Shirt~lnSearch Results~brGoogle~caApparel/T-Shirts~vaBlack~lp1~qt2~pr2.0',
                                          

          As you can see we can split the data within this parameter key by the tilde character ( ~ ) to be able to see a proper Product Model

          id: P12345
          nm: Android Warhol T-Shirt
          ln: Search Results
          br: Google
          ca: Apparel/T-Shirts
          va: Black
          qt: 2
          pr: 2.0
                                          
          ParameterValue TypeValue
          pr[0-9]idstringProduct ID/Sku
          nmstringProduct Name
          brstringProduct Brand
          castringProduct Category Hierarchy Level 1
          ca2stringProduct Category Hierarchy Level 2
          ca3stringProduct Category Hierarchy Level 3
          ca4stringProduct Category Hierarchy Level 4
          ca5stringProduct Category Hierarchy Level 5
          vastringProduct Variant
          prnumberProduct Unit Price
          qtintegerProduct Quantity
          cpstringProduct Coupon
          dsnumberProduct Discount

          Product Impressions

          These are the Measurement Protocol related parameters to the products Impressions. They are complimentary to the product items. Expect these on the product impressions and product clicks events

          ParameterValue TypeValue
          lnstringList Name
          listringList ID
          lpstringList Position

          Transaction Related Data

          The next table shows the parameters related to the transacion info.

          ParameterValue TypeValue
          ep.transaction_idstringTransaction ID
          ep.affiliationstringTransactionm Affiliation
          epn.valuenumberTransaction Revenue
          epn.taxnumberTransaction Tax
          epn.shippingnumberTransaction Shipping
          ep.couponstringTransaction Coupon

          Promotions

          And finally the next table shows the parameters related to the promotions tracking. We should expect these parematers to be showing up into the promotion views and promotion clicks events

          ParameterValue TypeValue
          pistringPromotion ID
          pnstringPromotion Name
          cnstringCreative Name
          csstringCreative Slot (Position )
          lostringLocationo ID