Skip to main content

Segment query language reference

Use ShopifyQL to query the GraphQL Admin API for segmentation data. Segmentation data represents data subsets, which users have created according to some criteria.

Segmentation data corresponds to saved search queries in the Shopify admin. For example, a user can save a segment for customers that are subscribed to email marketing. These customers are the segment members.

The following guide explains the syntax for forming queries.

Note

Segment queries don't support all ShopifyQL syntax.


Segmentation queries in API requests are precise definitions of segments. The queries indicate the condition or conditions that data must satisfy to be selected. The syntax performs a similar function to WHERE statements in SQL. Query syntax acts as a filter to determine the data returned.

For example, a segment query can retrieve segment members that have left a checkout without completing their purchase in the last 30 days.

You can query a maximum of 250 segments. The maximum value that first and last arguments accept is 250.


Segment queries are composed of a clause, or multiple clauses, specifying facts about the segment. The clauses specify a segment by applying a condition to an attribute using an operator.

An individual clause consists of the following components:

  • attribute: The properties that define all items in a specific category.
  • operator: A reserved character pattern that performs tasks such as comparisons and arithmetic operations.
  • condition: The state required for data to be either selected or filtered out.

The following is the query clause format:

<clause> ::= <attribute> <operator> <condition>

For example, in the following clause, email_subscription_status is the attribute, = is the operator, and SUBSCRIBED is the condition:

Segment query example

email_subscription_status = 'SUBSCRIBED'
An image of a query clause for customers who are subscribed by email

You can also group clauses.


An attribute's data type determines the valid operators and conditions for defining segment queries.

The following are supported attributes and their data types:

Attribute data types
AttributeData typeDescription
abandoned_checkout_dateDateThe date of the customer's abandoned checkout.
anniversary()FunctionThe customer with a yearly recurring date, such as a birth date.
amount_spentFloatThe total amount spent (all time).
companiesIntegerThe company ID for which the customer is configured as B2B contact.
created_by_app_idIntegerThe app ID that created the customer.
customer_account_statusEnumThe customer's account status.
customer_added_dateDateThe date when the customer was added on Shopify.
customer_citiesEnumThe customer's city.
customer_countriesEnumThe customer's country or region (shipping/billing).
customer_email_domainStringThe customer's email domains.
customer_languageStringThe customer's language.
customer_regionsEnumThe customer's region.
customer_tagsString

The customer's assigned tags.

Tag existence isn't validated.

customer_within_distanceFunctionThe customer with an address within a specified distance of a particular latitude, longitude.
email_subscription_statusEnumThe customer's email subscription status.
first_order_dateDateThe date of the customer's first order.
last_order_dateDateThe date of the customer's last order.
number_of_ordersIntegerThe number of orders for the customer (all time).
orders_placedFunctionThe orders that the customer placed (all time).
predicted_spend_tierEnumThe customer's predicted spend tier.
products_purchasedFunctionThe products that the customer purchased (all time).
product_subscription_statusEnumThe customer's status for product subscriptions.
rfm_groupEnumThe customer's RFM group.
sms_subscription_statusEnumThe customer's status for SMS subscriptions.
shopify_email.bouncedFunctionThe customer whose email was returned to the server that sent it.
shopify_email.clickedFunctionThe customer who clicked on any link or image in the email.
shopify_email.deliveredFunctionThe customer for whom the server has accepted an email.
shopify_email.marked_as_spamFunctionThe customer who reported an email using its mail client's "Mark as Spam", "Report", or "Junk" feature.
shopify_email.openedFunctionThe customer who opened an email on their email client.
shopify_email.unsubscribedFunctionThe customer who requested removal from the organization's email address list and can no longer be mailed.
store_credit_accountsFunctionThe customer who has store credit accounts.
storefront_event.collection_viewedFunctionThe customer who browsed a particular product collection.
storefront_event.product_viewedFunctionThe customer who browsed a particular product.

Boolean attributes support specific operators and conditions.

Note

The Segmentation API doesn't currently include Boolean-type attributes.

OperatorDescriptionExample
=Isboolean_attribute = true
!=Is notboolean_attribute != true

ConditionDescriptionExample
trueTrueboolean_attribute = true
falseFalseboolean_attribute = false

Date attributes support specific operators and conditions.

Date operators act on complete 24-hour days and default to a shop's time zone.

For example, a New York shop (GMT-4) with the following query would include customers who last ordered between midnight (T00:00:00) on May 30th, 2020 to midnight on May 31st, 2020 in the shop's timezone.

last_order_date = 2020-05-30

In SQL, with UTC-based times, this would look like the following:

last_order_date >= 2020-05-30T04:00:00 AND last_order_date < 2020-05-31T04:00:00

The following segment query would include customers who last ordered from midnight on May 31st:

last_order_date > 2020-05-30

The following are supported operators for date-type attributes.

OperatorsDescriptionExamples
=Equal-tolast_order_date = 2020-05-30
!=Not-equal-tolast_order_date != 2020-05-30
>Afterlast_order_date > 2020-05-30
>=On or afterlast_order_date >= 2020-05-30
<Beforelast_order_date < 2020-05-30
<=On or beforelast_order_date <= 2020-05-30
BETWEEN {condition1} AND {condition2}Equivalent to condition1 <= n <= condition2BETWEEN 2020-02-30 AND 2020-03-30

Date-type attributes accept specific conditions.

Language-sensitive formatted dates aren't accepted.

FormatExamples
yyyy-mm-ddRepresents an absolute date without time

Syntactic sugar for an absolute date without time. For example, if the date is May 15th 2021, then -7d is syntactic sugar for 2021-05-07.

The following are examples of {dateOffset}:

FormatDescriptionExamples
{+/-} {#} dNumber of dayslast_order_date > -7d
{+/-} {#} wNumber of weekslast_order_date >= -2w
{+/-} {#} mNumber of monthslast_order_date = -1m
{+/-} {#} yNumber of yearslast_order_date &lt; -1y

Syntactic sugar for an absolute date without time.

{namedDate} supports the following operators:

=, !=, >, >=, <, <=, BETWEEN

When using the BETWEEN operator, condition types can be mixed.

last_order_date BETWEEN 2021-01-01 AND today
last_order_date BETWEEN 2020-01-01 AND -7d
FormatDescriptionExamples
todayDate when the query is run or segment is queriedlast_order_date = today
yesterdayPrevious daylast_order_date = yesterday

The -12m, -90d, -30d, and -7d standard syntax is preferred to the now-deprecated 12_months_ago, 90_days_ago, 30_days_ago, and 7_days_ago syntax.

Anchor to [object Object]{absoluteDateTime}

In some cases, users might want finer segment granularity, such as the segment of customers that participated in a timed flash sale. The segmentation query syntax supports an absolute datetime in place of an absolute date.

Note

Assistive features for adding a time component aren't supported. Users are required to type these out manually.

FormatDescriptionExamples
yyyy-mm-ddTHH:mm:ssRepresents an absolute date with time in the shop's timezonelast_order_date > 2020-05-30T16:00:00

Times default to a shop's timezone. For example, a New York shop (GMT-4) with the following query would include customers means last_order_date > 2020-05-30T20:00:00 in UTC.

  • Only 24h format is supported. For example, HH needs to be be <= 23 (24h = 00:00:00).

  • Leading zeros are required, for example, 23:00:00.

  • Time-only syntax is not supported. For example, the following syntax is invalid:

last_order_date BETWEEN 1pm AND 3pm
  • You can't extend {namedDate} or {dateOffset} with a time-specifier.

Enum attributes support specific operators and conditions.

OperatorsDescriptionExample
=Equal-tocustomer_account_status = 'DISABLED'
!=Not-equal-tocustomer_account_status != 'DISABLED'

  • Conditions accept UTF-8 characters and must be wrapped with single quotes ', similar to the ENUM type in MySQL.

  • Conditions only accept a value chosen from a list of permitted values.

  • Conditions are case-sensitive and whitespaces are syntactically significant.

  • Single quotes within a condition must be escaped (ie. '\'VIP\'').

  • For Segmentation, we're using multiple clauses with connectors to specify multiple values.

Float attributes support specific operators and conditions. The underlying data type is a float64 (double-precision floating-point format).

OperatorsDescriptionExample
=Equal-toamount_spent = 10.99
!=Not-equal-toamount_spent != 10.99
>Greater thanamount_spent > 10.99
>=Greater than or equal toamount_spent >= 10.99
<Less thanamount_spent &lt; 10.99
<=Less than or equal toamount_spent <= 10.99
BETWEEN {value1} AND {value2}Equivalent to value1 <= n <= value2amount_spent BETWEEN 100 AND 1000.99

  • Conditions accept float (float64) and integer numbers.

  • Integers automatically get converted to floating point (ie. 99 => 99.0).

  • Operators and functions returning a Float, for example COUNT, SUM, MAX, and MEDIAN, aren't supported for querying segments.

Anchor to Formatting and separatorsFormatting and separators
  • A decimal point (.) is used as a decimal separator, by default.

  • Thousand separators, such as commas and spaces, aren't supported.

  • Language-sensitive formatted numbers aren't supported.

A Function accepts 0 or more parameters, individually supporting specific <operator>s and <condition>s that you can use to select specific customers. For example, products_purchased MATCHES (id = 1234, count > 1) would select all customers who purchased product id 1234 more than once.

  • Function names accept the same characters as regular filters, using lowercase alphanumerical and underscore (snake_case()).

  • Functions names are follow by either MATCHES or NOT MATCHES and parentheses enclosing the list of optional parameters.

  • Parameters are expressed by name with an appropriate, typed operator and value.

  • The previous syntax is now deprecated syntax (for example, `products_purchased (id: 1234) = true).

  • The anniversary expression is a modifier for a date filter, not a function. It determines whether a specified date falls on the annual anniversary of another data. For example, anniversary ('metafields.facts.birth_date') = today.

The segmentation query syntax has limited support for function-type attributes.

Anchor to [object Object]products_purchased

This function returns a Boolean. Supported <operator> values are = and !=.

For example,

products_purchased NOT MATCHES ()
products_purchased MATCHES (id = 2012162031638)
products_purchased MATCHES (tag = 'Sports wear')
products_purchased MATCHES (id IN (2012162031638, 1012132033639))

products_purchased MATCHES (id = ID | id IN List<ID>)

Where ID is a single value and List<ID> is a set of comma-separated values wrapped in parenthesis. An implicit OR between values is applied for lists.

Each ID is a product ID.

Notes
  • A single value in a list is valid.

  • Multiple values must be provided as a list. For example (1012132033639, 2012162031638, 32421429314657).

  • A list can contain up to 500 IDs.

For example,

products_purchased MATCHES (id = 1012132033639)
products_purchased MATCHES (id IN (1012132033639, 2012162031638, 32421429314657))
products_purchased MATCHES (id NOT IN (1012132033639))

Omitting the id parameter returns results for all products.

products_purchased MATCHES (tag = String)

Where tag is a product tag.

Notes
  • A single tag can be provided.

For example,

products_purchased MATCHES (tag = 'Sports wear')
products_purchased MATCHES (date = Date?)

Where

-- (inclusive)
Date = {absoluteDate} | {dateOffset} | {namedDate} | BETWEEN {date} AND {date}

This parameter is the date when the product was purchased.

For example,

products_purchased MATCHES (id = 1012132033639, date = 2022-01-01)
products_purchased NOT MATCHES (date > -3m)
products_purchased MATCHES (tag = 'Sports wear', date >= -12m)
products_purchased MATCHES (id = 1012132033639, date BETWEEN -12m AND today)

Omitting the date parameter returns results from all time.

Anchor to [object Object]shopify_email.EVENT()

Shopify Email functions enable segmenting on Shopify Email events. They are namespaced under the shopify_email. prefix. The following events are supported:

  • bounced
  • clicked
  • delivered
  • marked_as_spam
  • opened
  • unsubscribed

All of these functions accept the same named parameters and return a Boolean.

For example,

shopify_email.opened MATCHES ()
shopify_email.opened MATCHES (activity_id = 5240029206)
shopify_email.opened NOT MATCHES (activity_id = 5240029206)

shopify_email.EVENT MATCHES (activity_id = ID | activity_id IN List<ID>)

Where ID is a single value and List<ID> is a set of comma-separated values wrapped in parenthesis. An implicit OR between values is applied for lists.

Each ID is a marketing activity ID to filter on.

Notes
  • A single value in a list is valid.

  • Multiple values must be provided as a list. For example (5240029206, 1932881090, 3250045832).

  • A list can contain up to 500 IDs.

For example,

shopify_email.delivered MATCHES (activity_id = 5240029206)
shopify_email.opened MATCHES (activity_id IN (5240029206, 1932881090, 3250045832))
shopify_email.unsubscribed MATCHES (activity_id IN (5240029206))

Omitting the activity_id parameter returns results for all Shopify Email activities.

shopify_email.EVENT(date = Date?)

Where

-- (inclusive)
Date = {absoluteDate} | {dateOffset} | {namedDate} | BETWEEN {date} AND {date}

This parameter is the date for the Shopify Email event.

For example,

shopify_email.delivered MATCHES (activity_id = 5240029206, date = 2022-01-01)
shopify_email.marked_as_spam MATCHES (activity_id = 5240029206, date > -3m)
shopify_email.bounced NOT MATCHES (activity_id = 5240029206, date BETWEEN -12m AND today)

Omitting the date parameter returns results from all time.

Integer attributes are int64 types that support specific operators and conditions.

OperatorsDescriptionExample
=Equal-tonumber_of_orders = 10
!=Not-equal-tonumber_of_orders != 10
>Greater thannumber_of_orders > 10
>=Greater than or equal tonumber_of_orders >= 10
<Less thannumber_of_orders &lt; 10
<=Less than or equal tonumber_of_orders <= 10
BETWEEN {value1} AND {value2}Equivalent to value1 <= n <= value2number_of_orders BETWEEN 100 AND 1000

  • Conditions accept only integer numbers.

  • Floats aren't valid.

  • Minimum value of -9,223,372,036,854,775,808.

  • Maximum value of 9,223,372,036,854,775,807, inclusive.

  • Operators and functions returning a Float, for example COUNT, SUM, MAX, and MEDIAN, aren't supported for querying segments.

Anchor to Formatting and separatorsFormatting and separators
  • Thousand separators, such as commas and spaces, aren't supported.

  • Language-sensitive formatted numbers aren't supported.

List attributes represent multi-value attributes. The values in the list have a type.

The arguments the operator admits will depend on the type of the values within the list. An example is customer_tags, which is a multi-value list of strings. Its full type is therefore List<String>.

Lists support the following operators and conditions.

OperatorsDescriptionExample
CONTAINSAllows you to specify a single value ​​in a WHERE clause. The clause is true if the value matches an entry in the preceding list attribute.customer_tags CONTAINS 'vip'

customer_cities CONTAINS 'US-CA-LosAngeles'
NOT CONTAINSTrue complement of CONTAINS. The clause is true if the value does not match an entry in the preceding list attribute.customer_tags NOT CONTAINS 'vip'

customer_cities NOT CONTAINS 'US-CA-LosAngeles'

  • The semantics of CONTAINS as applied to a LIST is that the arguments must be a subset of the preceding list attribute.

  • Segmentation queries currently use multiple clauses with connectors to specify multiple values, rather than a multi-argument form.

  • String conditions accept UTF-8 characters and must be wrapped with single quotes ', similar to the ENUM type in MySQL.

  • Conditions are NOT case-sensitive and whitespaces are syntactically significant.

  • Single quotes within a condition must be escaped (ie. '\'VIP\'').

  • ID is an alias for an unsigned integer. The underlying data type is a uint64.

  • Conditions don't have to be wrapped in single quotes '.

String attributes support specific operators and conditions.

OperatorsDescriptionExample
=Equal-tocustomer_email_domain = 'example.com'
!=Not-equal-tocustomer_email_domain != 'example.com'

  • Conditions accept UTF-8 characters and must be wrapped around single quotes '.

  • Conditions are case-sensitive and whitespaces are syntactically significant.

  • Single quotes within a condition must be escaped. For example, '\'VIP\'').

  • Conditions can be empty strings. The API verifies that the attribute exists and is an empty string.

  • All operators/functions returning a String, such as CONCAT, SUBSTR, LOWER, UPPER, and TRUNCATE, are not supported for querying segments.

The following are syntax examples of grouped clauses.

Anchor to Multiple clauses with same connector(s)Multiple clauses with same connector(s)

Two clauses linked with AND

email_subscription_status = 'SUBSCRIBED' AND customer_countries CONTAINS 'CA'

Two clauses linked with OR

email_subscription_status = 'SUBSCRIBED' OR customer_countries CONTAINS 'CA'

Invalid query: Too many clauses (>10)

customer_countries CONTAINS 'CA' OR customer_countries CONTAINS 'FR' OR customer_countries CONTAINS 'MX' OR customer_countries CONTAINS 'AU' OR customer_countries CONTAINS 'AX' OR customer_countries CONTAINS 'AZ' OR customer_countries CONTAINS 'FI' OR customer_countries CONTAINS 'BE' OR customer_countries CONTAINS 'TH' OR customer_countries CONTAINS 'ES' OR customer_countries CONTAINS 'BR'

Anchor to Multiple clauses with different connectorsMultiple clauses with different connectors

By default AND takes precedence over OR. Parenthesis are optional. For example, the following queries are equivalent.

email_subscription_status = 'SUBSCRIBED' AND customer_countries CONTAINS 'CA' OR amount_spent > 999.99
(email_subscription_status = 'SUBSCRIBED' AND customer_countries CONTAINS 'CA') OR amount_spent > 999.99

Change implicit order of precedence: OR now takes precedence over AND

email_subscription_status = 'SUBSCRIBED' AND (customer_countries CONTAINS 'CA' OR amount_spent > 999.99)

Was this page helpful?