---
title: campaign_products
description: >-
  Reference for the ShopifyQL `campaign_products` schema. Every metric and
  dimension, paired with worked example queries.
api_version: 2026-10
source_url:
  html: >-
    https://shopify.dev/docs/api/shopifyql/latest/schemas/marketing/campaign_products
  md: >-
    https://shopify.dev/docs/api/shopifyql/latest/schemas/marketing/campaign_products.md
api_name: shopifyql
---

# campaign\_​products

The `campaign_products` [schema](https://shopify.dev/docs/api/shopifyql/latest/schemas) captures how many units of each product were sold as a result of marketing campaigns. Use it to see which products campaigns drive, compare attribution models, and link back to the campaign, session, and order behind each sale.

### Use cases

* **Attribution models**: Compare [`campaign_first_click_net_items_sold`](#campaignproductsmetric-propertydetail-campaignfirstclicknetitemssold), [`campaign_last_click_net_items_sold`](#campaignproductsmetric-propertydetail-campaignlastclicknetitemssold), and [`campaign_linear_net_items_sold`](#campaignproductsmetric-propertydetail-campaignlinearnetitemssold) for a product to see how the attribution model you pick changes its credited sales.
* **Product breakdown**: Group [`campaign_last_non_direct_click_average_order_quantity`](#campaignproductsmetric-propertydetail-campaignlastnondirectclickaverageorderquantity) by [`product_title`](#campaignproductsdimension-propertydetail-producttitle) or [`product_id`](#campaignproductsdimension-propertydetail-productid) to see which products campaigns move in larger quantities.
* **Traffic source**: Break down [`campaign_last_click_net_items_sold`](#campaignproductsmetric-propertydetail-campaignlastclicknetitemssold) by [`referring_channel`](#campaignproductsdimension-propertydetail-referringchannel) or [`utm_campaign`](#campaignproductsdimension-propertydetail-utmcampaign) to see which campaign sources drive product sales.
* **Order and session link**: Use [`order_id`](#campaignproductsdimension-propertydetail-orderid) and [`sa_token`](#campaignproductsdimension-propertydetail-satoken) to connect attributed products to orders and sessions.

Examples

### Examples

* ####

  ##### Description

  Rank one campaign's top 25 products this year by \`campaign\_last\_non\_direct\_click\_net\_items\_sold\`, beside the last-click, first-click, and linear models. This example uses \[\`WITH TOTALS\`]\(/docs/api/shopifyql/latest/syntax/with#total-columns) to total each model.

  ##### ShopifyQL

  ```shopifyql
  FROM campaign_products
    SHOW campaign_last_non_direct_click_net_items_sold,
      campaign_last_click_net_items_sold, campaign_first_click_net_items_sold,
      campaign_linear_net_items_sold
    WHERE campaign_id = 12345678
    GROUP BY product_title WITH TOTALS
    SINCE startOfYear(0y) UNTIL today
    ORDER BY campaign_last_non_direct_click_net_items_sold DESC
    LIMIT 25
  VISUALIZE campaign_last_non_direct_click_net_items_sold TYPE horizontal_bar
  ```

* ####

  ##### Description

  Show the monthly \`campaign\_linear\_net\_items\_sold\` for the 10 best-selling products this quarter. This example uses \[\`GROUP BY TOP 10\`]\(/docs/api/shopifyql/latest/syntax/group-by) to fold every other product into one remainder band.

  ##### ShopifyQL

  ```shopifyql
  FROM campaign_products
    SHOW campaign_linear_net_items_sold
    GROUP BY TOP 10 product_title WITH GROUP_TOTALS
    TIMESERIES month
    DURING this_quarter
    COMPARE TO previous_period
    ORDER BY month ASC, campaign_linear_net_items_sold DESC
  VISUALIZE campaign_linear_net_items_sold TYPE stacked_bar
  ```

* ####

  ##### Description

  Compare average order quantity across three attribution models, month by month this year. This example uses \[\`COMPARE TO previous\_year\`]\(/docs/api/shopifyql/latest/syntax/compare-to) with \[\`WITH PERCENT\_CHANGE\`]\(/docs/api/shopifyql/latest/syntax/with#percent-change-columns) to show how each month changed from last year.

  ##### ShopifyQL

  ```shopifyql
  FROM campaign_products
    SHOW campaign_first_click_average_order_quantity,
      campaign_last_click_average_order_quantity,
      campaign_last_non_direct_click_average_order_quantity
    TIMESERIES month WITH PERCENT_CHANGE
    DURING this_year
    COMPARE TO previous_year
    ORDER BY month ASC
  VISUALIZE campaign_last_non_direct_click_average_order_quantity TYPE bar
  ```

* ####

  ##### Description

  Rank the 10 \`sa\_token\` values driving the most \`campaign\_first\_click\_net\_items\_sold\` last month. This example uses \[\`GROUP BY\`]\(/docs/api/shopifyql/latest/syntax/group-by) \`sa\_token\` to collapse sales into one row per token before \`LIMIT 10\` trims the result.

  ##### ShopifyQL

  ```shopifyql
  FROM campaign_products
    SHOW campaign_first_click_net_items_sold
    GROUP BY sa_token WITH TOTALS
    DURING last_month
    ORDER BY campaign_first_click_net_items_sold DESC
    LIMIT 10
  VISUALIZE campaign_first_click_net_items_sold TYPE horizontal_bar
  ```

***

## Metrics

Counts and calculations that let you track key business indicators. Metrics show up as the columns when queried.

Metrics you can use when querying `FROM campaign_products`.

* **campaign\_​first\_​click\_​average\_​order\_​quantity**

  **DECIMAL**

  The average order quantity for orders where campaign credit goes to the customer's first touchpoint across devices.

  `First click average order quantity = (products + gift cards) / orders`

* **campaign\_​first\_​click\_​net\_​items\_​sold**

  **INTEGER**

  Items sold credited to the customer's first campaign touchpoint across devices, after returns are accounted for.

  `First click net items sold = products + gift cards`

* **campaign\_​last\_​click\_​average\_​order\_​quantity**

  **DECIMAL**

  The average order quantity for orders where campaign credit goes to the final session in the customer's journey.

  `Last click average order quantity = (products + gift cards) / orders`

* **campaign\_​last\_​click\_​net\_​items\_​sold**

  **INTEGER**

  Items sold credited to the final session in the customer's journey, after returns are accounted for.

  `Last click net items sold = products + gift cards`

* **campaign\_​last\_​non\_​direct\_​click\_​average\_​order\_​quantity**

  **DECIMAL**

  The average order quantity for orders where campaign credit goes to the customer's final non-direct campaign session across devices.

  `Last non-direct click average order quantity = (products + gift cards) / orders`

* **campaign\_​last\_​non\_​direct\_​click\_​net\_​items\_​sold**

  **INTEGER**

  Items sold credited to the customer's final non-direct campaign session across devices, after returns are accounted for.

  `Last non-direct click net items sold = products + gift cards`

* **campaign\_​linear\_​average\_​order\_​quantity**

  **DECIMAL**

  The average order quantity for orders where campaign credit is shared across touchpoints in the linear cross-device attribution model.

  `Linear average order quantity = (products + gift cards) / orders`

* **campaign\_​linear\_​net\_​items\_​sold**

  **DECIMAL**

  The net quantity of products and gift cards sold, credited by the linear cross-device attribution model, with shared credit shown as decimal values. Use [`campaign_linear_net_items_sold`](#campaignproductsmetric-propertydetail-campaignlinearnetitemssold) by [`campaign_id`](#campaignproductsdimension-propertydetail-campaignid) or [`product_title`](#campaignproductsdimension-propertydetail-producttitle) to see item sales credited across campaign touchpoints.

  `Linear net items sold = products + gift cards`

### DECIMAL

Number stored with a fixed number of decimal places for exact calculations

```ts
```

### INTEGER

Whole number without decimal places, used for counts and quantities

```ts
```

***

## Dimensions

Attributes of your data that let you look more granularly at aspects of the data. Group and filter by dimensions to shape the rows your query returns.

Dimensions you can use when querying `FROM campaign_products`.

* **campaign\_​id**

  **IDENTITY**

  Unique identifier for the campaign

* **customer\_​id**

  **IDENTITY**

  Shopify identifier for the customer

* **day**

  **DAY\_TIMESTAMP**

  The day a campaign-driven order was processed.

* **day\_​of\_​week**

  **DAY\_OF\_WEEK**

  The day of the week a campaign-driven order was processed, with values Monday through Sunday.

* **hour**

  **HOUR\_TIMESTAMP**

  The hour a campaign-driven order was processed.

* **hour\_​of\_​day**

  **HOUR\_OF\_DAY**

  The hour of day a campaign-driven order was processed, with values 0 through 23.

* **is\_​first\_​cross\_​device**

  **BOOLEAN**

  Whether the campaign session is the customer's first touchpoint in the journey across devices, with values `true` and `false`.

* **is\_​last**

  **BOOLEAN**

  Whether the campaign session is the final session in the customer's journey, with values `true` and `false`.

* **is\_​last\_​non\_​direct\_​cross\_​device**

  **BOOLEAN**

  Whether the campaign session is the final non-direct session in the customer's journey across devices, with values `true` and `false`.

* **linear\_​model\_​attribution\_​weight\_​cross\_​device**

  **DECIMAL**

  The portion of campaign credit this session receives across devices in the linear attribution model, shown as a decimal.

* **marketing\_​activity\_​url\_​parameter\_​key**

  **STRING**

  Values are free-text parameter names from campaign URLs.

* **marketing\_​activity\_​url\_​parameter\_​value**

  **STRING**

  Values are free-text tracking values paired with [`marketing_activity_url_parameter_key`](#campaignproductsdimension-propertydetail-marketingactivityurlparameterkey) in campaign URLs.

* **marketing\_​event\_​id**

  **IDENTITY**

  Unique identifier for the associated marketing event

* **month**

  **MONTH\_TIMESTAMP**

  The month a campaign-driven order was processed.

* **month\_​of\_​year**

  **MONTH\_OF\_YEAR**

  The month of year a campaign-driven order was processed, with values 1 through 12.

* **new\_​or\_​returning\_​customer**

  **STRING**

  Whether the order came from a customer's first purchase (New) or a later purchase (Returning).

* **normalized\_​page\_​url**

  **STRING**

  Normalized URL of the page

* **order\_​id**

  **IDENTITY**

  Shopify identifier for the order

* **order\_​processed\_​at**

  **TIMESTAMP**

  The exact time when the order was processed, reported in your store's time zone.

* **page\_​host**

  **STRING**

  The domain of the page associated with the campaign session, such as your store's domain.

* **page\_​path**

  **STRING**

  The path portion of the landing page URL for the campaign-driven session, the part after the domain. You can group or filter by [`page_path`](#campaignproductsdimension-propertydetail-pagepath) to compare campaign results by page.

* **product\_​id**

  **IDENTITY**

  The unique Shopify identifier for the product. You can group or filter by [`product_id`](#campaignproductsdimension-propertydetail-productid) to compare campaign results by product, with [`product_title`](#campaignproductsdimension-propertydetail-producttitle) labeling those results by product name.

* **product\_​title**

  **STRING**

  The title of the product tied to the campaign-driven order.

* **quarter**

  **QUARTER\_TIMESTAMP**

  The quarter a campaign-driven order was processed.

* **referrer\_​url**

  **STRING**

  The referring page that sent the visitor to your store.

* **referring\_​channel**

  **STRING**

  Channel that led to an online store session

* **referring\_​medium**

  **STRING**

  The broad traffic category that brought the visitor to the online store session, based on the referring channel.

* **referring\_​platform**

  **STRING**

  Platform that led to an online store session

* **sa\_​token**

  **STRING**

  Token associated with the session

* **shop\_​id**

  **IDENTITY**

  The unique Shopify identifier for your store. Use [`shop_id`](#campaignproductsdimension-propertydetail-shopid) with [`shop_name`](#campaignproductsdimension-propertydetail-shopname) to show readable store labels.

* **traffic\_​type**

  **STRING**

  Classifies the online store session as Direct, Paid, Organic, Unknown, or Unattributed.

* **utm\_​campaign**

  **STRING**

  The UTM campaign name from the tagged link associated with the session. Values are the text used in your campaign URLs.

* **utm\_​content**

  **STRING**

  The UTM content value from the tagged link associated with the session. Values are the text used to distinguish ads, links, or creative in your campaign URLs. Use [`utm_content`](#campaignproductsdimension-propertydetail-utmcontent) to compare campaign content.

* **utm\_​medium**

  **STRING**

  The UTM medium value from the tagged link associated with the session. Values are the text used for the marketing method, such as email or social.

* **utm\_​source**

  **STRING**

  The UTM source value from the tagged link associated with the session. Values are the text used for the source in your campaign URLs.

* **utm\_​term**

  **STRING**

  The UTM term value from the tagged link associated with the session. Values are the search term or keyword text used in your campaign URLs. Use [`utm_term`](#campaignproductsdimension-propertydetail-utmterm) to compare campaign-driven product orders by keyword.

* **week**

  **WEEK\_TIMESTAMP**

  The week a campaign-driven order was processed.

* **week\_​of\_​year**

  **WEEK\_OF\_YEAR**

  The week of year a campaign-driven order was processed, with values 1 through 53.

* **year**

  **YEAR\_TIMESTAMP**

  The year a campaign-driven order was processed.

* **customer\_​amount\_​spent**

  **MONEY**

  The customer's all-time spend is shown in your store's currency.

* **customer\_​last\_​order\_​date**

  **DAY\_TIMESTAMP**

  The day the customer most recently placed an order, reported in your store's time zone.

* **customer\_​number\_​of\_​orders**

  **INTEGER**

  Number of orders the customer has placed across all time

* **shop\_​name**

  **STRING**

  Name of your store

### IDENTITY

Unique identifier for a Shopify resource such as a customer or order

```ts
```

### DAY\_TIMESTAMP

Date with the time of day removed

```ts
```

### DAY\_OF\_WEEK

Day of the week, used to group or filter data by weekday

```ts
```

### HOUR\_TIMESTAMP

Date and time with minutes and seconds removed

```ts
```

### HOUR\_OF\_DAY

Hour of the day, shown as a whole number from 0 to 23

```ts
```

### BOOLEAN

Value that is either true or false

```ts
```

### STRING

Text made of letters, numbers, or symbols

```ts
```

### MONTH\_TIMESTAMP

Date for the start of a month

```ts
```

### MONTH\_OF\_YEAR

Month number within a year

```ts
```

### TIMESTAMP

Date and time recorded at the most detailed available level

```ts
```

### QUARTER\_TIMESTAMP

Date for the start of a fiscal quarter

```ts
```

### WEEK\_TIMESTAMP

Date for the start of a week

```ts
```

### WEEK\_OF\_YEAR

Week number within a year

```ts
```

### YEAR\_TIMESTAMP

Date for the start of a year

```ts
```

### MONEY

Currency amount such as a price, revenue, cost, or discount

```ts
```

***

## Related schemas

* [`campaign_sales`](https://shopify.dev/docs/api/shopifyql/latest/schemas/marketing/campaign_sales): Order-level campaign attribution when you want revenue rather than unit volume per product.
* [`campaign_sessions`](https://shopify.dev/docs/api/shopifyql/latest/schemas/marketing/campaign_sessions): Upstream funnel signals from the same campaign sessions.
* [`marketing_engagements`](https://shopify.dev/docs/api/shopifyql/latest/schemas/marketing/marketing_engagements): App-level engagement metrics when you want ad spend and click data paired with attributed sales.

***
