← Back to Metrics

Promotion Clicks

Also known as: Internal Promotion Clicks, Promo Clicks, Banner Clicks, Select Promotion Events, Internal Campaign Clicks

EngagementmetricE-commerce: Product Discovery & Merchandising (Search/Filters/PDP)E-commerce

Count of clicks on internal promotions such as banners and hero tiles, from the GA4 select_promotion event. It is the numerator of Promotion Click-Through Rate, with Promotion Views as the denominator.

Business Use Case

1️⃣ Merchandising compares clicks per creative_slot weekly and moves the strongest offer into the hero slot.,2️⃣ Marketing sees a campaign banner's clicks fall after launch week and swaps the creative or ends the promotion early.,3️⃣ Merchandising pairs clicks with Promotion Views to rank promotions by CTR before the next homepage refresh.

Business Criticality

High

Journey / Navigation Area

Discovery

Owning Function

Merchandising

Scope

Event

Formula

COUNT(select_promotion events) in the reporting period, excluding internal and bot traffic, grouped by promotion_id, promotion_name and creative_slot

Calculation Notes

1️⃣ Counts select_promotion events, not items: a banner click carrying three items counts once; GA4 Items clicked in promotion counts three.,2️⃣ Every click counts, including repeat clicks by the same user; distinct users or sessions measure reach, not this metric.,3️⃣ Promotion fields resolve from item-level values first, then event-level, as in GA4; a click with neither reports (not set).,4️⃣ Ad and email clicks belong to Ad Clicks and Email Clicks. Recommendation clicks are tracked as select_item, so they never enter this count.,5️⃣ Excludes internal and bot traffic (traffic_type) and duplicate hits with the same user, timestamp and promotion_id.,6️⃣ Dated by event timestamp in the property time zone; a click that fails to send before navigation is lost and understates the count.

Technical Details

Measure TypeCounter
Aggregation WindowDaily, Weekly, Monthly

Events

PlatformEvent
Google Analytics 4select_promotion
Adobeselect_promotion

Data Mappings

W3 Data Layer
{
  "digitalData": {
    "event": [
      {
        "eventInfo": {
          "eventName": "select_promotion",
          "eventAction": "click"
        },
        "attributes": {
          "promotion_id": "PROMO-1",
          "promotion_name": "promo",
          "creative_name": "banner",
          "creative_slot": "slot-1",
          "traffic_type": "external"
        }
      }
    ],
    "page": {
      "category": {
        "pageType": "home"
      }
    }
  }
}
GA4 Data Layer
{
  "event": "select_promotion",
  "promotion_id": "PROMO-1",
  "promotion_name": "promo",
  "creative_name": "banner",
  "creative_slot": "slot-1",
  "page_type": "home",
  "traffic_type": "external",
  "ecommerce": {
    "items": [
      {
        "item_id": "SKU-1",
        "item_name": "item",
        "promotion_id": "PROMO-1",
        "promotion_name": "promo",
        "creative_slot": "slot-1"
      }
    ]
  }
}
Adobe Client Data Layer
{
  "event": "select_promotion",
  "eventInfo": {
    "promotion_id": "PROMO-1",
    "promotion_name": "promo",
    "creative_name": "banner",
    "creative_slot": "slot-1",
    "page_type": "home",
    "traffic_type": "external"
  },
  "productListItems": [
    {
      "SKU": "SKU-1",
      "promotion_id": "PROMO-1",
      "promotion_name": "promo",
      "creative_slot": "slot-1"
    }
  ]
}
XDM Mapping
{
  "eventType": "web.webinteraction.linkClicks",
  "web": {
    "webInteraction": {
      "name": "select_promotion",
      "type": "other",
      "linkClicks": {
        "value": 1
      }
    }
  },
  "productListItems": [
    {
      "SKU": "SKU-1",
      "_tenantId": {
        "promotionID": "PROMO-1",
        "promotionName": "promo",
        "creativeSlot": "slot-1"
      }
    }
  ],
  "_tenantId": {
    "trafficType": "external",
    "pageType": "home",
    "promotion": {
      "promotionID": "PROMO-1",
      "promotionName": "promo",
      "creativeName": "banner",
      "creativeSlot": "slot-1"
    }
  }
}

SQL Queries

Google Analytics 4 (BigQuery)
-- ==========================================
-- 1. GOOGLE BIGQUERY SQL
-- ==========================================
DECLARE start_date DATE DEFAULT DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY);
DECLARE end_date DATE DEFAULT DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY);

-- One row per select_promotion event (not per item); promotion fields resolve item-level first, then event-level, else (not set)
WITH clicks AS (
  SELECT
    user_pseudo_id,
    event_timestamp,
    COALESCE(
      (SELECT MAX(i.promotion_id) FROM UNNEST(items) AS i),
      (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'promotion_id'),
      '(not set)') AS promotion_id,
    COALESCE(
      (SELECT MAX(i.promotion_name) FROM UNNEST(items) AS i),
      (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'promotion_name'),
      '(not set)') AS promotion_name,
    COALESCE(
      (SELECT MAX(i.creative_slot) FROM UNNEST(items) AS i),
      (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'creative_slot'),
      '(not set)') AS creative_slot,
    (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'traffic_type') AS traffic_type
  FROM `your-project.analytics_123456789.events_*`
  -- event_date suffix is already in the property time zone
  WHERE _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', start_date) AND FORMAT_DATE('%Y%m%d', end_date)
    AND event_name = 'select_promotion'
),

-- Drop internal and bot traffic, and duplicate hits with the same user, timestamp and promotion_id
deduped AS (
  SELECT *
  FROM clicks
  WHERE IFNULL(traffic_type, '') NOT IN ('internal', 'bot')
  QUALIFY ROW_NUMBER() OVER (PARTITION BY user_pseudo_id, event_timestamp, promotion_id ORDER BY event_timestamp) = 1
)

-- Promotion Clicks: every remaining click counts, repeat clicks included
SELECT
  promotion_id,
  promotion_name,
  creative_slot,
  COUNT(*) AS promotion_clicks
FROM deduped
GROUP BY promotion_id, promotion_name, creative_slot
ORDER BY promotion_clicks DESC;
Adobe Experience Platform (AEP Query Service)
-- ==========================================
-- 2. ADOBE AEP QUERY SERVICE SQL
-- ==========================================
-- Relative reporting window: last 90 complete days
WITH params AS (
  SELECT date_sub(current_date(), 90) AS start_date,
         date_sub(current_date(), 1) AS end_date
),

-- One row per select_promotion event (not per item); promotion fields resolve productListItems first, then event-level, else (not set)
clicks AS (
  SELECT
    identityMap['ECID'][0].id AS ecid,
    timestamp,
    COALESCE(
      array_max(transform(productListItems, i -> i._tenantId.promotionID)),
      _tenantId.promotion.promotionID,
      '(not set)') AS promotion_id,
    COALESCE(
      array_max(transform(productListItems, i -> i._tenantId.promotionName)),
      _tenantId.promotion.promotionName,
      '(not set)') AS promotion_name,
    COALESCE(
      array_max(transform(productListItems, i -> i._tenantId.creativeSlot)),
      _tenantId.promotion.creativeSlot,
      '(not set)') AS creative_slot,
    _tenantId.trafficType AS traffic_type
  FROM aep_web_events, params
  WHERE web.webInteraction.name = 'select_promotion'
    -- dated in the property time zone (set to the reporting time zone)
    AND to_date(from_utc_timestamp(timestamp, 'America/New_York')) BETWEEN params.start_date AND params.end_date
),

-- Drop internal and bot traffic, and duplicate hits with the same user, timestamp and promotion_id
deduped AS (
  SELECT *
  FROM (
    SELECT
      *,
      ROW_NUMBER() OVER (PARTITION BY ecid, timestamp, promotion_id ORDER BY timestamp) AS rn
    FROM clicks
    WHERE COALESCE(traffic_type, '') NOT IN ('internal', 'bot')
  ) t
  WHERE rn = 1
)

-- Promotion Clicks: every remaining click counts, repeat clicks included
SELECT
  promotion_id,
  promotion_name,
  creative_slot,
  COUNT(*) AS promotion_clicks
FROM deduped
GROUP BY promotion_id, promotion_name, creative_slot
ORDER BY promotion_clicks DESC;

Source Data

Digital Analytics (GA4)

Dependencies

Prerequisite: List the dependencies required for this Metric

Events:

promotion-click

Report Attributes

promotion_id promotion_name creative_name creative_slot page_type device-category traffic-source

Recommended Reporting Views

Views
Onsite Merchandising PerformanceInternal Promotion PerformanceHomepage Content Effectiveness

Segment Eligibility

true

Governance

Data SensitivityInternal

Derived KPIs

Governance

Created bydevyendarm
Created on10/12/2026
Last modified bydevyendarm
Last modified on10/12/2026
StatusPUBLISHED

GitHub

View related Pull Requestcatalog/metrics/promotion-clicks.yml

Community Discussion