Skip to main content

Analytics

Shopify Analytics puts your app's data in the reports and dashboards that merchants already use, and you don't need to run your own data infrastructure. Model your data into Shopify Analytics, query the data with ShopifyQL, embed live charts in your app, add annotations that explain the numbers, and set targets for the numbers to reach. AI agents that query analytics for merchants read the same data.

ShopifyQL is the query language behind Shopify Analytics. The metric cards, dashboards, and reports in the Shopify admin run on ShopifyQL. Your app reads analytics data with ShopifyQL. You build on ShopifyQL with four building blocks: model, query, embed, and enrich.

For example, an email marketing app uses all four building blocks:

  • Model your app's data: add a campaign_source metafield to orders and send an email_sent App Event. Merchants query the campaign_source metafield and the email_sent event beside store data.
  • Query the data with ShopifyQL through the GraphQL Admin API: run a query like FROM app_events SHOW emails_sent GROUP BY app_name.
  • Embed the results with a web component: show the query results on the app's dashboard with the <s-shopifyql-metric-card> metric card.
  • Enrich the charts with an annotation: mark a date, such as the day a campaign goes live, and the store's charts show the marker beside the metric's change.
Four building blocks on ShopifyQL, the query layer behind Shopify Analytics: model, query, embed, and enrich.

Anchor to Model your app's data into Shopify AnalyticsModel your app's data into Shopify Analytics

Merchants query your app's data in Shopify Analytics, and you don't need a separate analytics store. The data comes from metafields on Shopify records such as orders and customers, the metaobjects that the metafields reference, or App Events that your app sends.

Mark a metafield definition as analytics-queryable, and ShopifyQL exposes the metafield's values as a dimension beside store data. For example, add a campaign_source metafield to an order or a subscription_status metafield to a customer. Merchants can then group, filter, and chart reports on the metafield. Shopify already stores the metafield values.

When a merchant assigns a product category, Shopify adds category metafields for that category's attributes, such as color, size, and material. Category metafields are queryable in ShopifyQL under the shopify namespace with no setup, for example product.metafields.shopify.material. Results show the label of the taxonomy attribute value that the merchant selected, such as Organic cotton. Results don't show a metaobject ID. Use CONTAINS to filter on a category metafield, because a product can have more than one value for an attribute. Wrap attribute names that contain a hyphen in double quotes, like product.metafields.shopify."color-pattern".

When a product, product variant, customer, or order metafield references a metaobject, you can query that metaobject's fields through the metafield by adding the field key to the end. For example, if a product's custom.designer metafield points to a Designer metaobject, then product.metafields.custom.designer.country is a dimension. If the metafield references a list of metaobjects, then the metaobject field returns a list. Use CONTAINS to filter a list field.

To make a metaobject's fields queryable, enable the analyticsQueryable capability on its metaobject definition with the metaobjectDefinitionCreate or metaobjectDefinitionUpdate mutation, available in GraphQL Admin API version 2027-01 and later. The definition must include at least one field of a type that analytics supports, such as text, number, or date. Query the capability's eligible field to check whether a definition qualifies. Merchants can also turn on the capability in the Shopify admin with the Filter or group data in Analytics setting on the metaobject definition.

Queries follow the reference from the record to the metaobject. You can't start from a metaobject and query the records that point to it.

ShopifyQL query

FROM sales
SHOW total_sales
GROUP BY order.metafields.my_app.campaign_source

App Events makes your app's events queryable in Shopify Analytics. Declare your events and send the events through the App Events API. Merchants then query the events in ShopifyQL. With App Events in Analytics, one query can compare the same event across every installed app.

ShopifyQL query

FROM app_events
SHOW emails_sent
GROUP BY app_name

Anchor to Query analytics with ShopifyQLQuery analytics with ShopifyQL

GraphQL Admin API

query {
shopifyqlQuery(
query: "FROM sales SHOW total_sales, orders TIMESERIES month DURING last_year"
) {
tableData {
columns { name dataType }
rows
}
parseErrors
}
}

Anchor to Embed analytics with web componentsEmbed analytics with web components

Use analytics web components to show the Shopify admin's charts to app users in your app. Each component runs a ShopifyQL query and handles chart rendering, currency formatting, and locale formatting for your app.

Metric card

<s-shopifyql-metric-card
heading="Total sales"
query="FROM sales
SHOW total_sales
TIMESERIES day WITH TOTALS, PERCENT_CHANGE
DURING last_month
COMPARE TO previous_period
VISUALIZE total_sales TYPE line"
></s-shopifyql-metric-card>
A ShopifyQL metric card with the heading Total sales, showing the total with its percent change from the previous period above a line chart of daily total sales for the last month.

Anchor to Enrich analytics with annotations and targetsEnrich analytics with annotations and targets

An annotation is a dated note that explains why a metric moved. Shopify records your app as the annotation's creator in the createdByApp field. A loyalty app can mark the day a program launched, an email app can mark a campaign, and a subscription app can mark a pricing change. Create annotations with the analyticsAnnotationCreate mutation on the GraphQL Admin API, read them with analyticsAnnotations, and overlay them on a chart in ShopifyQL with ANNOTATE.

A metric target is a goal for a metric, such as total sales for the quarter. Merchants track progress against the goal in reports and dashboards. Create targets with the analyticsTargetCreate mutation on the GraphQL Admin API, read them with analyticsTargets, and compare against them in ShopifyQL with COMPARE TO TARGETS.

GraphQL Admin API

mutation {
analyticsAnnotationCreate(input: {
type: "campaign"
title: "Email campaign sent"
startedAt: "2026-02-06T09:00:00Z"
}) {
analyticsAnnotation { id type title }
userErrors { field message }
}
}

GraphQL Admin API

mutation {
analyticsTargetCreate(input: {
metric: "total_sales"
name: "Q3 sales target"
startDate: "2026-07-01"
endDate: "2026-09-30"
expectedValue: "50000.00"
}) {
analyticsTarget { id name metric expectedValue }
userErrors { field message }
}
}

Anchor to Build a campaign dashboardBuild a campaign dashboard

ShopifyQL query

FROM sales
SHOW total_sales, orders, new_customers, total_sales_first_time
TIMESERIES day WITH TOTALS, PERCENT_CHANGE
SINCE 2026-07-22 UNTIL 2026-08-04
COMPARE TO previous_period, previous_year
ORDER BY day ASC

Was this page helpful?