When AI engines like ChatGPT and Claude recommend retail products, they bypass visual page elements and extract structured data to identify the best deals. On Shopify, default structured data filters omit subscription pricing because Selling Plans exist outside standard variant models. As a result, cost-conscious buyers querying AI agents for the cheapest recurring options never see your discount offers. To solve this, you must explicitly inject your recurring pricing into your JSON-LD using UnitPriceSpecification, allowing Pendium to verify your offers are fully discoverable across every major AI platform in 2026.
Identify what AI agents actually see right now
As an AI visibility platform, Pendium has analyzed how major Large Language Models (LLMs) scrape retail websites to make product recommendations. To understand what these bots see, you must inspect your raw server-side HTML. Open your Shopify product page in a browser, right-click, and select "View Page Source." Do not rely on your browser's developer console or "Inspect Element" feature. The developer console displays the Document Object Model (DOM) after client-side JavaScript execution, whereas many AI crawlers fetch raw HTML to minimize processing overhead.
Search the raw source code for <script type="application/ld+json">. If your subscribe-and-save pricing is managed entirely by a third-party script widget that renders after the page loads, the crawler will miss your subscription offer completely. The bot reads only the static, one-time purchase price.
Shopify includes a native Liquid filter called structured_data ({{ product | structured_data }}) that converts product objects into schema markup automatically. While this filter is helpful for basic fields, research from Anglera on Shopify product JSON-LD integration confirms that it leaves out advanced attributes like subscription selling plans, GTINs, and stock status.
For direct-to-consumer businesses, this creates a major vulnerability. We analyze this dynamic in our breakdown of AI visibility for DTC brands, where merchants lose recommendation volume because AI agents assume their products only retail at the standard, non-discounted rate.
Map Shopify selling plans to the correct schema format
Our technical team at Pendium designed this schema mapping process to solve this breakdown. To make your subscription offers readable, you must represent them using Schema.org structural elements inside your existing JSON-LD block.
The standard one-time offer
A basic Shopify product page outputs a standard Offer object. This object contains the default price, currency, and availability. It looks like this:
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Organic Coffee Beans",
"offers": {
"@type": "Offer",
"price": "20.00",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock"
}
}
This structure is fine for traditional search engines displaying simple snippets. However, it fails to convey any recurring options or discount incentives to AI engines that calculate long-term costs for users.
The subscribe-and-save specification
To communicate subscription rates, you must expand the Offer object using the priceSpecification array. Technical documentation on formatting subscription offers for AI agents outlines the exact structure required to represent a recurring purchase path.
Each subscription option is declared as a UnitPriceSpecification. This specification requires a declared referenceQuantity containing a value and a unitCode to represent the shipping interval.
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Organic Coffee Beans",
"offers": {
"@type": "Offer",
"price": "20.00",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"priceSpecification": [
{
"@type": "UnitPriceSpecification",
"priceType": "https://schema.org/ListPrice",
"price": "20.00",
"priceCurrency": "USD"
},
{
"@type": "UnitPriceSpecification",
"name": "Subscribe & Save 15%",
"price": "17.00",
"priceCurrency": "USD",
"referenceQuantity": {
"@type": "QuantitativeValue",
"value": 30,
"unitCode": "DAY"
}
}
]
}
}
By presenting both pricing models in a single structured list, AI crawlers can instantly compare the list price ($20.00) against the subscription rate ($17.00). The model now understands that the customer can choose a 30-day recurring delivery option to secure the lower price.
Connect your subscription app to your JSON-LD output
Solving this indexing problem across different subscription engines is a core requirement for maintaining high scores on the Pendium platform. Most Shopify subscription tools write their data natively through Shopify's Selling Plans API. This means whether you use Recharge, Stay AI, Skio, Loop, or Appstle, the underlying pricing structures are stored consistently in your store's backend.
To output this data automatically, we can construct a Liquid loop in your theme files. Create a snippet that checks for active selling plans on the current product.
{%- assign current_variant = product.selected_or_first_available_variant -%}
{%- assign has_selling_plans = false -%}
{%- if product.selling_plan_groups.size > 0 -%}
{%- assign has_selling_plans = true -%}
{%- endif -s%}
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"name": {{ product.title | json }},
"image": {{ product.featured_image | image_url: width: 1024 | json }},
"description": {{ product.description | strip_html | escape | json }},
"sku": {{ current_variant.sku | json }},
"offers": {
"@type": "Offer",
"price": "{{ current_variant.price | money_without_currency | remove: ',' }}",
"priceCurrency": "{{ cart.currency.iso_code }}",
"availability": "https://schema.org/{% if current_variant.available %}InStock{% else %}OutOfStock{% endif %}",
"priceSpecification": [
{
"@type": "UnitPriceSpecification",
"priceType": "https://schema.org/ListPrice",
"price": "{{ current_variant.price | money_without_currency | remove: ',' }}",
"priceCurrency": "{{ cart.currency.iso_code }}"
}
{%- if has_selling_plans -%}
{%- for group in product.selling_plan_groups -%}
{%- for plan in group.selling_plans -%}
{%- comment -%} Calculate the plan discount {%- endcomment -%}
{%- assign allocation = current_variant.selling_plan_allocations | where: "selling_plan", plan | first -%}
{%- if allocation -%}
,{
"@type": "UnitPriceSpecification",
"name": {{ plan.name | json }},
"price": "{{ allocation.per_delivery_price | money_without_currency | remove: ',' }}",
"priceCurrency": "{{ cart.currency.iso_code }}",
"referenceQuantity": {
"@type": "QuantitativeValue",
"value": 30,
"unitCode": "DAY"
}
}
{%- endif -%}
{%- endfor -%}
{%- endfor -%}
{%- endif -%}
]
}
}
</script>
This Liquid script loops through the product's available allocations to pull the real price calculation for each plan. It formats the data server-side so it populates directly inside the initial HTML payload sent to the crawlers.
For brands using standard configurations, certain applications designed to manage search data can automatically inject this subscription metadata. The guide from Ilana Davis on subscription prices in rich results notes that tools natively tied to Shopify's checkout engine can write these updates to the schema automatically, bypassing the need for manual theme edits.

How to avoid competing schema blocks on Shopify
Our AI visibility platform frequently flags stores with duplicate schema records. This is a common hazard when merchants attempt to optimize their code. If your Shopify theme outputs a default Product schema block, and you install a second app or custom snippet that injects an optimized block, the page will contain multiple disjointed descriptions.
This scenario confuses search indexers and AI crawlers. When an LLM reads two competing schemas, it cannot easily determine which one is accurate. This often leads to the engine discarding the enriched subscription data entirely, or worse, hallucinating pricing from a mix of both records.
To prevent this confusion, you must consolidate your structured data into a single, unified source. Locate the Liquid files in your theme (often main-product.liquid or product.liquid) and find the code rendering the default schema. Comment out or delete this block, then insert your unified custom file that handles variants, combined structures, and selling plans together.
To see how complex setups can cause similar crawler issues, refer to our guide on structuring Shopify combined listings schema. Resolving these overlapping blocks is a straightforward way to keep your store's data stream clear and trustworthy for scrapers.
Verify your metadata changes with Pendium tools
Once your theme files are updated and deployed, you need to verify that AI models can read the new schema. Traditional markup tools will only tell you if Google's search crawler finds the syntax valid. They will not tell you if conversational assistants are successfully reading your discount programs.
To inspect how the models process your store, run your product URL through the Pendium AI visibility scan. The platform simulates real buyer profiles and tests live queries across seven major systems, including ChatGPT, Claude, and Gemini.
Using this data-driven approach, you can see if the models are recognizing your subscribe-and-save offers. When your structured data is correctly formatted, the AI platforms will begin recommending your recurring purchase pricing directly, driving higher-value subscriptions to your store.