context parameter in search, browse, blocks, and facet requests accepts the following structured data. The snippets below show the value for a single context key, not a top-level request body. All fields must be nested inside the context object.
Geographic information
Location data used for regional merchandising and localized search results. For client-side requests, Layers automatically determines the customer’s location based on their IP address. For headless integrations making server-side API calls, you should pass geo information explicitly.Products in cart
Current cart contents help surface complementary products and influence relevance scoring.title(string, optional): Product titleprice(number, optional): Unit price in the request currency’s major units (e.g.110.00for $110), not cents. Accepts a JSON number or a numeric string such as"110.00".type(string, optional): Product typeproductId(string, optional): Shopify product ID. Accepts numeric or GID string form.variantId(string, optional): Shopify variant IDoptions(object, optional): Key-value pairs of variant optionsquantity(integer, optional): Number of units of this line in the cart. Accepts a number or numeric string, such as2,2.0, or"2". Layers rounds fractional values down to a whole number. Missing values, non-numeric values, and values below1count as1.
- Each entry needs at least a
productId,variantId, or non-emptytitle. Layers drops entries with none of these and records a developer notice. - If an optional field is malformed, such as a non-numeric
price, Layers removes only that field and keeps the rest of the entry. - Cart-anchored blocks use every entry with a valid
productIdas an anchor product, not just the first. Layers removes duplicate products while preserving cart order. Entries without aproductIdaren’t used as block anchors. - Title-only entries still work in contextual conditions that match on product title.
Free shipping threshold
The cart subtotal at which the shopper qualifies for free shipping. Free Shipping Picks blocks use it withproductsInCart prices and quantities to recommend products that close the gap.
freeShippingThreshold(number, optional): Threshold in the request currency’s major units (e.g.75.00for $75), not cents. Accepts a number or a numeric string, such as"75.00".
- If the value is missing, non-numeric, or not greater than
0, Layers ignores it. The request still succeeds, and Layers keeps the rest of the context. - The app embed doesn’t send this field. Pass it yourself on requests for Free Shipping Picks blocks.
Recently viewed products
Products the shopper has viewed during the current session. Layers uses these as short-lived personalization signals (more recent views carry more weight than older ones), so search and browse results lean toward the categories, brands, and attributes the shopper is actively exploring.id(string, optional): Shopify product ID. Accepts numeric or GID string form. Also accepted asproductIdfor parity with the other product arrays.at(integer, optional): Timestamp of the view in Unix milliseconds. Enables recency-based weighting; views withoutatstill count but skip time decay.title(string, optional): Product title.type(string, optional): Product type.variantId(string, optional): Shopify variant ID, if the shopper viewed a specific variant.options(object, optional): Key-value pairs of variant options.
- Only the 20 most recently viewed products are used. If you send more, extras are silently dropped (newest first by
at). - Very old views (well beyond the current session) contribute little to no signal, so there’s no need to prune the list yourself.
- The Storefront Pixel populates
productsViewedautomatically. Only send it manually for headless integrations.
Purchase history
Previously purchased products inform recommendations and prevent over-promotion of already-owned items.title(string, optional): Product titleprice(number, optional): Unit price in the request currency’s major units (e.g.110.00for $110), not cents, at time of purchase. Accepts a JSON number or a numeric string such as"110.00".type(string, optional): Product typeproductId(string, optional): Shopify product IDvariantId(string, optional): Shopify variant IDat(integer, optional): Timestamp of the purchase in Unix milliseconds. Required for Products Purchased conditions that use a time window and for the Replenish strategy.options(object, optional): Key-value pairs of variant options
productId, variantId, or non-empty title.
Prior searches
Recent search queries and their outcomes help understand customer intent and refine relevance models.searchQuery(string, required): The search query text. Layers drops entries with a missing or empty query.hadClick(boolean, optional): Whether the customer clicked on any results. Defaults tofalsewhen omitted,null, or not a boolean.hasResults(boolean, optional): Whether the search returned any results. Defaults tofalsewhen omitted,null, or not a boolean.fromPage(string, optional): The page the search was started from, such as the referring page URL or page type. Layers accepts this field but doesn’t currently use it for ranking or rules.
Marketing attribution
UTM parameters and marketing campaign information for attribution tracking.source(string, optional): Marketing source (e.g., “google”, “facebook”)medium(string, optional): Marketing medium (e.g., “cpc”, “email”, “social”)campaign(string, optional): Campaign nameterm(string, optional): Search term or keywordcontent(string, optional): Ad or link variant, such as the value ofutm_contentclickIds(object, optional): Click identifiers appended to the landing URL by ad networks and email/SMS platforms, keyed by parameter name (e.g.,fbclid,gclid). Layers uses these to derive a click source when the link carries no UTMs.referrer(string, optional): The site that linked the shopper to the storefront, as a host or full URL (e.g., “google.com”). Layers normalizes it to a lowercase host withoutwww..landingPath(string, optional): The storefront path the shopper first landed on this visit (e.g., “/collections/sale”). Layers removes the query string and fragment and keeps up to 512 characters.channel(string, optional): The arrival channel. Layers derives this value on the server, see Arrival channel.
Click identifiers and derived click source
Ad networks append click identifiers to landing URLs even when the link was never tagged with UTMs. Send those identifiers inmarketing.clickIds and Layers derives the originating network as marketing.clickSource. You can use the derived value in contextual conditions and analytics segmentation alongside the UTM fields.
Layers uses the raw click identifiers only to derive clickSource. The identifier values themselves are not recorded in analytics events.
Supported parameters and the network they resolve to:
Behavior:
- Parameter names match case-insensitively (Snapchat’s
ScCidresolves the same assccid). Unknown keys are ignored. - When multiple identifiers are present, ad networks take precedence over the email/SMS platforms (Klaviyo, Listrak). A Klaviyo-tagged link shared and clicked on Facebook resolves to
meta. - A value is only honored when it is a non-empty string of 512 characters or fewer. Invalid values are skipped without affecting the UTM fields.
- Layers derives only the network and discards the raw identifier tokens. They are never stored or inspected beyond the checks above.
- The derived value never overwrites
marketing.source. Merchant-declared UTMs stay authoritative. fbclidresolves tometa, notfacebook, because it cannot distinguish a Facebook click from an Instagram one.
A click source is not proof of a paid ad. Meta, for example, appends
fbclid to organic link clicks too, so Layers derives only the source and never infers marketing.medium. Targeting a specific ad still requires UTM-tagged links.Arrival channel
Layers classifies every visit into one arrival channel,marketing.channel, from the other marketing fields. The Storefront Pixel captures the referring site and landing page at the start of each visit and sends them as marketing.referrer and marketing.landingPath. Classification always happens on the server, so the same visit gets the same channel in requests, tracking events, and orders.
Layers uses the first signal that applies:
-
UTMs: When
sourceormediumis set, the channel follows the medium. For example,cpcmaps topaid_search(orpaid_socialfor social sources),emailtoemail,smstosms,affiliatetoaffiliate,organictoorganic_search, andsocialtosocial. Other mediums map toreferral, or toai_assistantwhen the source is a known AI assistant. Mediums are matched case-insensitively, and common alternative spellings count as the same medium: -
Click identifiers: When the visit has a derived click source, the channel follows the network. Google and Microsoft map to
paid_search, Meta tosocial, other ad networks topaid_social, and Klaviyo and Listrak toemail. -
Campaign only: When only
campaignis set, Layers leaves the channel empty. -
Referring site: Layers matches the referrer host against known search engines, AI assistants, social networks, and email providers. Visits referred by Android apps are recognized too: the Gmail app counts as
emailand the Google app counts asorganic_search. Any other host is classified asreferral. -
Direct: When none of the above apply and the visit has a landing path, the channel is
direct.
- When the visit has no UTMs and the referring site is recognized, Layers also fills
sourceandmedium. A visit from Google search, for example, gets sourcegoogleand mediumorganic. An unrecognized site gets its host as the source andreferralas the medium. UTMs you send are never overwritten. - Your own storefront domains, including custom domains, and checkout and payment hosts are not treated as referring sites. A shopper who returns from checkout or moves between your domains doesn’t start a new referral.
- A
channelyou send is kept only when Layers can’t derive one, and only if it’s one of the values above. Other values are dropped. - Tracking events get the same server-side
channelandclickSourceas requests, and their referring site is stored in the same normalized form, sowww.google.comandgoogle.comreport as one referring site. AclickSourceyou send on an event is kept only when Layers can’t derive one, and only if it’s one of the supported networks above. - An order takes the channel of the visit it came from. When that visit has no channel, for example because the pixel didn’t record it, Layers classifies the order from its own UTM source, medium, and campaign using the same rules. The visit’s channel always wins over the order’s UTMs. An order with no UTMs is left without a channel instead of being counted as
direct. An order’s click source always comes from its visit.
Experiments
Theexperiments object records which A/B test group the shopper is in for each running experiment. Keys are experiment IDs and values are group IDs.
Customer profile
Aggregated customer behavior and purchase patterns for personalization.signedIn(boolean, optional): Whether the customer is currently authenticatedreturning(boolean, optional): Whether this is a returning customernumberOfOrders(integer, optional): Total number of orders placedaverageOrderValue(float, optional): Average order value in store currencydaysBetweenOrders(integer, optional): Average days between ordersdaysSinceLastOrder(integer, optional): Days since the most recent orderdaysSinceOldestOrder(integer, optional): Days since the first ordertotalSpent(float, optional): Total amount spent in store currencytags(array of strings, optional): Shopify customer tags on the shopper’s profile. Collected by the Storefront Pixel for signed-in customers;nullfor guests. Available ascontext.customer.tagsin contextual conditions.segments(array of integers, server-resolved): Shopify customer segment IDs the shopper belongs to. Populated by Layers from the signed-inidentity.customerIdon every request; any client-supplied value is ignored.nullfor guests and customers with no segment memberships. Available ascontext.customer.segmentsin contextual conditions.
Market
Identifies the Shopify Market for the current request. Used for market-specific product availability filtering, contextual pricing, and market-targeted merchandising rules.market(string, optional): The market identifier. Accepts a two-letter country code (e.g.,"US","CA"), a numeric Shopify Market ID (e.g.,"12345"), a Shopify Market GID (e.g.,"gid://shopify/Market/12345"), or a market handle.marketId(number, optional): A direct active Shopify Market ID accepted by Search and Browse when no explicit market selector is sent. For Blocks, usemarketto select a market explicitly.
context.market (or top-level market when context.market is absent) takes precedence. With no explicit selector, Layers uses context.marketId if it names an active market, then the shopper’s country (via context.geo.country or request geolocation), then the active primary market. If an explicit selector doesn’t resolve, Layers falls back to country and primary market resolution without trying context.marketId. An unknown or inactive direct ID also falls back to country and primary market resolution.
Layers resolves pricingCountryCode and baseCurrencyCode on the server and strips client-supplied values for those fields. Choose a market and supply the shopper’s country instead of setting these derived fields. The base currency determines the currency of fixed-amount discount entitlements.
Once the market is resolved, Layers picks a pricing country inside that market, because prices are stored per country within a market. It checks, in order:
- A country code in
context.market. Whencontext.marketis a two-letter country code (for example, from a storefront market switcher) and that country belongs to the resolved market, Layers prices for that country. A deliberate country selection wins over the shopper’s detected location. For example, a shopper browsing from the US who selects Philippines receives PHP-denominated prices for the Philippines region of the resolved market. - The shopper’s country. Otherwise, Layers uses
context.geo.country(or the IP-detected country) if it belongs to the resolved market. - A fallback country in the market. If neither applies (for example, the shopper is outside the market, or a server-side request omits
geo.countryso the detected country is your server’s), Layers uses the market’s only country for single-country markets, or the first country alphabetically by country code for multi-country markets.
context.geo.country (or a country code in context.market) to make sure shoppers get their own country’s prices.
Application modes:
The store’s market application mode is set in the Layers dashboard under Settings > Search & Discovery > Search Behavior, in the Markets card. It controls how the resolved market affects results:
- Restrict to market catalog: Only products available in the resolved market appear in results, and market-specific pricing is applied to variants
- Adjust pricing only: All products remain visible, but variant prices are swapped to market-specific values where available
- Ignore markets (default): Market resolution is skipped entirely; the base catalog and base pricing apply for all shoppers
price_range and variant price fields in API responses reflect the market-specific prices rather than the store’s base currency prices.
Session
Session-level signals about the current visit. Used for merchandising rules that adapt to new vs. returning sessions and for analytics segmentation.returning(boolean, optional): Whether the current session belongs to a returning visitor. Layers derives this from the storefront’s session cookie when not provided.
Locale
The active storefront locale for the request. Used for localized merchandising and analytics segmentation.locale(string, optional): Storefront locale code (e.g.,"en","fr","pt-br"). Case-insensitive; Layers normalizes to lowercase.
Currency
The currency applied to the request. Used for analytics segmentation and to ensure event data records the currency the shopper actually saw.currency(string, optional): ISO 4217 currency code (e.g.,"USD","EUR"). Case-insensitive; Layers normalizes to uppercase. When Layers can resolve a currency from the shopper’s market or pricing context, the server-resolved value takes precedence over the client-supplied one.
B2B company
The Shopify B2B company location associated with a signed-in company account. Used for B2B-specific merchandising, pricing, and analytics segmentation.b2bCompany(string, optional): Shopify B2B company location identifier. Whenidentity.companyLocationIdis provided, Layers resolves the company location server-side and the server value takes precedence.
Device type
Use device type to target phones, desktop browsers, tablets, or bots in contextual conditions. Fields:deviceType(string, optional): Accepts"mobile","desktop","tablet", or"bot". An explicit value takes precedence over automatic detection.
User-Agent when you omit it, even when you send no other context. For server-side integrations, pass the shopper’s device type explicitly so conditions don’t use your server’s user agent. If device information is unavailable, Layers leaves device type unset rather than assuming mobile or desktop.
Tablets have their own category. Device type is independent of shopping channel: a phone browser can have device type "mobile" and shopping channel "web".
Shopping channel
Identifies the channel the customer is browsing from (web browser vs mobile app). Used for channel-specific merchandising rules, sorting, and analytics segmentation.shoppingChannel(string, optional): The shopping channel. Accepted values:"web"(default) or"app". When not provided, Layers detects the channel from request headers (e.g., mobile app requests via Fuego, Tapcart or Mobiloud Canvas are detected as"app").
Custom context
Additional custom contextual data specific to your implementation.custom field accepts any arbitrary key-value pairs for implementation-specific context that doesn’t fit into the standard categories. Values can be scalars or objects nested one level deep (for example, "loyalty": { "tier": "platinum" }).
The Storefront Pixel stamps several well-known keys into custom automatically:
page(string): The pathname of the storefront page that issued the request or event, for example/products/hat. Stamped at send time, so it always reflects the page the shopper was on.query(object): The current page’s non-attribution query parameters (for example,{ "filter.v.option.color": "red" }). Attribution and internal parameters (UTMs, ad click IDs, keys starting with_) are excluded, and recorded values are filtered for sensitive-looking content before storage (see Usage and privacy). A storefront can override or clear the captured params by settingcustom.queryexplicitly.clickedSection/clickedBlock(strings): The theme section and block IDs the shopper clicked on the previous page, reported once with the next page’s context. These power the Clicked Section and Clicked Block condition fields.
Complete context example
This example shows every availablecontext field: